Compare commits

...

81 Commits

Author SHA1 Message Date
20c09d8b0a 1.14.04 Fix methode name usersReportExport 2024-10-21 21:20:09 +02:00
4c88d7a71d Revert "Fix bug parametre de langue inutile dans RFM"
This reverts commit 889e2754fc.
2024-10-20 16:13:29 +02:00
bb9b8b086f 1.14.03 et non 1.14.04 2024-10-20 16:10:04 +02:00
61752a9a51 Optimisation récupérationstatistiques individuelle, la méthode getReports peut retourner les stats d'un utilisateur 2024-10-20 16:07:58 +02:00
889e2754fc Fix bug parametre de langue inutile dans RFM 2024-10-20 16:06:56 +02:00
77b241c69f 1.14.04 TEST Empêche qu'un espace réservé aux membres ne reste ouvert après une déconnexion de la session 2024-10-17 10:40:50 +02:00
442b84a99d Commente un test de validation de la consultation d'un espace 2024-10-16 12:27:32 +02:00
09f9f6bdd6 Optimisation setData 2024-10-12 11:16:44 +02:00
5eace20e26 Fix position d'un bouton 2024-10-12 11:10:58 +02:00
18df3848f8 Update Blog and News 2024-10-12 11:02:08 +02:00
7b9d145533 supprime console.log 2024-10-12 08:15:54 +02:00
75ad5853cf 1.14.03 fix subword 2024-10-10 19:59:53 +02:00
7862815f1f 1.14.02 Module blog bug de présentation, version 7.12 2024-10-08 15:23:51 +02:00
a87d439282 fix update store 2024-10-03 12:01:59 +02:00
509c1d6365 Bug de changement de mot de passe 2024-10-02 19:00:05 +02:00
e641ec1c03 Fix module checkup 2024-10-02 12:40:51 +02:00
3dec8a8ce5 Points virgules !! 2024-10-02 12:18:36 +02:00
54f0b0c6e3 redondance de déclaration de charset 2024-10-02 12:12:52 +02:00
931e59db2e Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCampus 2024-10-02 11:54:16 +02:00
cae0e6c8fb fix reset password key check 2024-10-02 11:54:11 +02:00
afee77b1e7 fix reset password key check 2024-10-02 11:50:19 +02:00
cf8963248e Merge branch 'reste_user_message' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCampus into reste_user_message 2024-10-02 07:56:09 +02:00
22af8ac751 message rest password 2024-10-02 07:56:04 +02:00
2d4385f038 :q 2024-10-02 07:52:40 +02:00
c4bb124bea Init 2024-09-30 19:22:08 +02:00
a474a41402 init 2024-09-30 18:50:31 +02:00
e9f65a1e22 Bug de connexion quand le site est à la racine 2024-09-30 15:38:15 +02:00
8183b0bb0b Install optimisation config 2024-09-29 18:55:30 +02:00
585c888007 supprime un log 2024-09-29 16:00:58 +02:00
d0997ccbf9 Version 1.13.00 2024-09-29 14:17:19 +02:00
1a6bfab54b Supprimer les traceurs de process de stockage 2024-09-29 14:12:32 +02:00
23f38a606f Forçage inutile 2024-09-28 18:34:10 +02:00
f1e1989c97 Corrections Rémi, optimisations 2024-09-28 17:54:05 +02:00
9bb5793720 save = false and saveDB 2024-09-28 15:34:00 +02:00
64443322a0 Merge branch 'master' into write_process 2024-09-28 13:32:46 +02:00
76258c835f 1.12.00.16 restaure l'onglet étiquette dans la configuration 2024-09-28 13:30:48 +02:00
dc81614114 init WIP 2024-09-28 13:24:55 +02:00
8dc1adc28a 1.12.00.15 Position d'un bouton de la vlidation dans la configuration 2024-09-27 10:25:20 +02:00
65eac4ac4a 1.12.00.14 user vide écrit au logout 2024-09-26 19:58:00 +02:00
a8f70dc73a suscribe 2.3 2024-09-26 19:42:24 +02:00
02aeb6ec22 readme 2024-09-26 14:25:19 +02:00
5bdb38dfec Message modification tag(s) 2024-09-26 10:54:13 +02:00
5700200bc3 erreur de commentaire 2024-09-26 10:51:19 +02:00
4ffca0e34a 1.12.00.13 bug initialisation et content dans le script RFM 2024-09-26 10:42:30 +02:00
f4553110e1 1.12.00.12 inverse la position des icones users et config 2024-09-19 10:52:07 +02:00
bf3b1f9cb0 suscribe 2.2 enum 2024-09-19 10:47:20 +02:00
05d8ae9e0b 1.12.00.11 empêche la saisie des caractères interdits lors de l'auto inscription dans le champ id du login 2024-09-19 10:43:24 +02:00
6128d0778d 2.2 register 2024-09-19 10:41:32 +02:00
c38bd7d12f 1.12.00.10 Erreur d'initialisation 2024-09-19 09:59:59 +02:00
cd509dfcb1 Suppression du cookie configLayout 2024-09-18 19:33:59 +02:00
5ab8efe72e 1.12.00.09 supprime le cookie pageLayout 2024-09-18 19:01:44 +02:00
6cf6a8d6b2 numéro de version 2024-09-18 10:19:05 +02:00
daaf309b4d Numero de version 2024-09-18 10:17:46 +02:00
2d5c395aec numérotation et changes 2024-09-17 19:14:03 +02:00
5d5b1e3140 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCampus 2024-09-17 19:05:27 +02:00
8aa24e50ab 1.12.08 empêche la déconnexion après la modification du compte connecté 2024-09-17 19:05:21 +02:00
8574970bb0 1.12.08 corrige l'affichage des flèches de navigation dans les vues des modules 2024-09-17 18:23:32 +02:00
89e6e12748 1.12.08 supprime le cookie relatif au contenu de site sans passer par main.php 2024-09-17 17:52:57 +02:00
9234b76062 1.12.08 change 2024-09-16 23:42:58 +02:00
08c1619162 1.12.08 suppression du cookie ZWII_SITE_CONTENT 2024-09-16 23:40:59 +02:00
576f349b4a changes 2024-09-16 23:01:40 +02:00
be6eaa748e 1.12.07 la clé n'a pas été déclarée 2024-09-16 22:55:58 +02:00
1dc7b08d2e 1.12.06 Index correct 2024-09-16 21:24:17 +02:00
35521766cd 1.12.06 Chemin du cookie de session 2024-09-16 21:20:35 +02:00
c8ee063963 1.12.05 modification du cookie de consentement 2024-09-15 19:00:40 +02:00
f0aba44ddb 1.12.05 icone plugin rouge si module mis à jour 2024-09-15 17:54:25 +02:00
e6236e5de2 readme 2024-09-09 20:55:20 +02:00
e5629de660 1.12.04 Complète l'ide de site avec le chemin 2024-09-08 15:00:06 +02:00
92d3da27a3 1.12.03 2024-09-07 18:17:24 +02:00
1fd0c5492f 1.12.03 bouton de génération du sitemap 2024-09-07 14:25:47 +02:00
bab06033ed 1.11.03 bloque les bots sauf les moteurs 2024-09-07 14:12:22 +02:00
f7cf0f94fc Search 3.3 une seule lecture de module 2024-09-07 09:53:54 +02:00
c244651b62 readme ! 2024-09-07 08:53:38 +02:00
beb58da3bd rfm thumb config 2024-09-07 08:18:40 +02:00
8756162428 1.12.01 default RFM thumb size 2024-09-07 08:11:24 +02:00
511a6ff0bb csrf key sur 64 octets 2024-09-06 17:18:17 +02:00
4175ff828d 1.12.00 Méthode d'authentification 2024-09-06 17:16:04 +02:00
087b5d9999 1.11.01 isole la session dans l'onglet 2024-09-06 09:35:12 +02:00
fea1c40a4b Bug datatables ajout dans user 2024-09-06 09:08:21 +02:00
2dce24f9f2 Bug datatables 2024-09-06 09:06:52 +02:00
0e0fd23913 version 1.11.00 2024-09-06 08:39:12 +02:00
74 changed files with 2234 additions and 1714 deletions

View File

@ -1,4 +1,4 @@
# ZwiiCampus 1.11.00
# ZwiiCampus 1.14.00
ZwiiCampus (Learning Management System) est logiciel auteur destiné à mettre en ligne des tutoriels. Il dispose de plusieurs modalités d'ouverture et d'accès des contenus. Basé sur la version 13 du CMS Zwii, la structure logicielle est solide, le framework de Zwii est éprouvé.

View File

@ -673,10 +673,30 @@ class helper
public static function subword($text, $start, $length)
{
$text = trim($text);
if (strlen($text) > $length) {
// Vérifier si la longueur du texte sans les balises dépasse la longueur souhaitée
if (mb_strlen(strip_tags($text)) > $length) {
// Utiliser mb_substr pour couper le texte
$text = mb_substr($text, $start, $length);
$text = mb_substr($text, 0, min(mb_strlen($text), mb_strrpos($text, ' ')));
// S'assurer que le texte ne se termine pas au milieu d'un mot
$lastSpace = mb_strrpos($text, ' ');
if ($lastSpace !== false) {
$text = mb_substr($text, 0, $lastSpace);
}
// Fermer les balises HTML ouvertes
$dom = new DOMDocument();
@$dom->loadHTML('<div>' . $text . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$text = $dom->saveHTML();
// Retirer la balise de conteneur ajoutée
$text = preg_replace('~^<div>(.*)</div>$~s', '$1', $text);
// Ajouter des points de suspension si le texte a été coupé
$text .= '...';
}
return $text;
}

View File

@ -156,21 +156,21 @@ class JsonDb extends \Prowebcraft\Dot
// Essaye d'écrire les données encodées dans le fichier de base de données
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
// $now = \DateTime::createFromFormat('U.u', microtime(true));
// file_put_contents("tmplog.txt", '[JsonDb][' . $now->format('H:i:s.u') . ']--' . $this->db . "\r\n", FILE_APPEND);
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
break;
}
// Incrémente le compteur de tentatives
$attempt++;
}
// Vérifie si l'écriture a échoué même après plusieurs tentatives
if ($write_result !== $encoded_length) {
// Enregistre un message d'erreur dans le journal des erreurs
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
// Affiche un message d'erreur et termine le script
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
}

View File

@ -82,17 +82,25 @@ class layout extends common
$content = 'col' . $blocks[1];
$blockright = 'col' . $blocks[2];
}
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
$pattern = ['config', 'edit', 'add', 'comment', 'data'];
// Toujours en pleine page pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
$pattern = ['config', 'edit', 'add', 'comment', 'data', 'option', 'theme', 'comment', 'article', 'data', 'gallery', 'update', 'users', 'validate'];
if (
(sizeof($blocks) === 1 ||
in_array($this->getUrl(1), $pattern))
) { // Pleine page en mode configuration
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top') {
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top')
&& in_array($this->getUrl(1), $pattern) === false
) {
$this->showNavButtons('top');
}
$this->showContent();
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom') {
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom')
&& in_array($this->getUrl(1), $pattern) === false
) {
$this->showNavButtons('bottom');
}
} else {
@ -330,7 +338,7 @@ class layout extends common
// Affichage du lien de connexion
if (
($this->getData(['theme', 'footer', 'loginLink'])
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
)
or $this->getUrl(0) === 'theme'
) {
@ -352,11 +360,11 @@ class layout extends common
$items .= $this->getData(['theme', 'footer', 'displaymemberAccount']) === false ? ' class="displayNone">' : '>';
$items .= '<wbr>&nbsp;|&nbsp;';
if (
$this->getUser('permission', 'filemanager') === true
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none'
$this->getUser('permission', 'filemanager') === true
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none'
) {
$items .= '<wbr>' . template::ico('folder', [
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&fldr=/' . self::$siteContent,
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&fldr=/' . self::$siteContent,
'margin' => 'all',
'attr' => 'data-lity',
'help' => 'Fichiers du site'
@ -520,8 +528,10 @@ class layout extends common
) {
// Affiche l'icône RFM
if ($this->getUser('permission', 'filemanager') === true
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none') {
if (
$this->getUser('permission', 'filemanager') === true
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none'
) {
$itemsRight .= '<li>' . template::ico('folder', [
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&fldr=/' . self::$siteContent,
'attr' => 'data-lity',
@ -547,7 +557,7 @@ class layout extends common
// Lien de connexion
if (
($this->getData(['theme', 'menu', 'loginLink'])
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
)
or $this->getUrl(0) === 'theme'
) {
@ -592,9 +602,9 @@ class layout extends common
if (
($this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) or ($this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -658,9 +668,9 @@ class layout extends common
$items .= '<li id=' . $childKey . '>';
if (
($this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) or ($this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -754,7 +764,7 @@ class layout extends common
$items .= '<li class="menuSideChild">';
if (
$this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) {
$items .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -778,7 +788,7 @@ class layout extends common
if (
$this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) {
$itemsChildren .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -914,7 +924,7 @@ class layout extends common
*/
public function showBar()
{
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
if ($this->isConnected() === true) {
// Items de gauche
$leftItems = '';
// Sélecteur de contenu
@ -931,7 +941,7 @@ class layout extends common
}
$leftItems .= '</select></li>';
}
$leftItems .= '<li>' . template::ico('cubes', [
'href' => helper::baseUrl() . 'course',
'help' => 'Gérer les espaces'
@ -1016,53 +1026,53 @@ class layout extends common
)
// Sur une page d'accueil
or $this->getUrl(0) === ''
) {
// Bouton Editer une page
if (
$this->getUser('permission', 'page', 'edit')
and $this->geturl(1) !== 'edit'
) {
// Bouton Editer une page
if (
$this->getUser('permission', 'page', 'edit')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('pencil', [
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Éditer la page'
]) . '</li>';
}
// Bouton Editer le module d'une page
if (
$this->getUser('permission', 'page', 'module')
and $this->geturl(1) !== 'edit'
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
) {
$leftItems .= '<li>' . template::ico('gear', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'help' => 'Module de la page'
]) . '</li>';
}
// Bouton dupliquer une page
if (
$this->getUser('permission', 'page', 'duplicate')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('clone', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Dupliquer la page'
])
. '</li>';
}
// Bouton Effacer une page
if (
$this->getUser('permission', 'page', 'delete')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('trash', [
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Supprimer la page',
'id' => 'pageDelete'
])
. '</li>';
}
$leftItems .= '<li>' . template::ico('pencil', [
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Éditer la page'
]) . '</li>';
}
// Bouton Editer le module d'une page
if (
$this->getUser('permission', 'page', 'module')
and $this->geturl(1) !== 'edit'
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
) {
$leftItems .= '<li>' . template::ico('gear', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'help' => 'Module de la page'
]) . '</li>';
}
// Bouton dupliquer une page
if (
$this->getUser('permission', 'page', 'duplicate')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('clone', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Dupliquer la page'
])
. '</li>';
}
// Bouton Effacer une page
if (
$this->getUser('permission', 'page', 'delete')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('trash', [
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Supprimer la page',
'id' => 'pageDelete'
])
. '</li>';
}
}
}
// Items de droite
$rightItems = '';
@ -1076,7 +1086,7 @@ class layout extends common
) {
$rightItems .= '<li>' . template::ico('folder', [
'help' => 'Fichiers',
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&fldr=/' . self::$siteContent,
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&fldr=/' . self::$siteContent,
'attr' => 'data-lity'
]) . '</li>';
}
@ -1084,22 +1094,18 @@ class layout extends common
self::$siteContent === 'home'
&& $this->getUser('group') >= self::GROUP_ADMIN
) {
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
$rightItems .= '<li>' . template::ico('flag', [
'help' => 'Langues',
'href' => helper::baseUrl() . 'language'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration',
'href' => helper::baseUrl() . 'config'
]) . '</li>';
$rightItems .= '<li>' . template::ico('users', [
'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration',
'href' => helper::baseUrl() . 'config'
]) . '</li>';
// Mise à jour automatique
$today = mktime(0, 0, 0);
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
@ -1111,21 +1117,54 @@ class layout extends common
$today > $checkUpdate + $this->getData(['config', 'autoUpdateDelay', 86400])
) {
// Dernier auto controle
$this->setData(['core', 'lastAutoUpdate', $today]);
$this->setData(['core', 'lastAutoUpdate', $today], false);
if (
helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)
) {
$this->setData(['core', 'updateAvailable', true]);
$this->setData(['core', 'updateAvailable', true], false);
}
// Modules installés
$infoModules = helper::getModules();
// Recherche de mise à jour des modules
$store = plugin::getStore();
if (is_array($store)) {
// Parcourir les données des modules du store
foreach ($store as $key => $value) {
if (empty($key)) {
continue;
}
// Mise à jour d'un module
// Le module est installé et une mise à jour est en ligne
if (
isset($infoModules[$key])
&&
version_compare($infoModules[$key]['version'], $value['version'], '<')
) {
$this->setData(['core', 'updateModuleAvailable', true], false);
}
}
}
// Sauvegarde la base manuellement
$this->saveDB('core');
}
}
// Afficher le bouton : Mise à jour détectée + activée
if ($this->getData(['core', 'updateAvailable'])) {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'install/update" data-tippy-content="Mettre à jour Zwii ' . common::ZWII_VERSION . ' vers ' . helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) . '">' . template::ico('update colorRed') . '</a></li>';
}
}
if ($this->getData(['core', 'updateModuleAvailable'])) {
$rightItems .= '<li>' . template::ico('puzzle colorRed', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
} else {
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
}
// Boutons depuis le groupe éditeur
if (
$this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUser('permission', 'user', 'edit')
@ -1213,7 +1252,7 @@ class layout extends common
$vars = 'var baseUrl = ' . json_encode(helper::baseUrl(false)) . ';';
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and $this->getUser('group') >= self::GROUP_EDITOR
) {
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';

View File

@ -11,7 +11,7 @@ class core extends common
parent::__construct();
// Token CSRF
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128));
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(64));
}
// Fuseau horaire
@ -32,8 +32,6 @@ class core extends common
}
// Date de la dernière suppression
$this->setData(['core', 'lastClearTmp', $lastClearTmp]);
// Enregistre les données
//$this->SaveData();
}
// Backup automatique des données
$lastBackup = mktime(0, 0, 0);
@ -423,7 +421,7 @@ class core extends common
)
) {
// Stocke la dernière page vue et sa date de consultation
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)]);
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)], false);
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'datePageView', time()]);
// Stocke le rapport en CSV
@ -438,7 +436,7 @@ class core extends common
// Force la déconnexion des membres bannis ou d'une seconde session
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and ($this->getUser('group') === common::GROUP_BANNED
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
@ -452,8 +450,8 @@ class core extends common
$this->getData(['config', 'maintenance'])
and in_array($this->getUrl(0), ['maintenance', 'user']) === false
and $this->getUrl(1) !== 'login'
and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and ($this->isConnected() === false
or ($this->isConnected() === true
and $this->getUser('group') < common::GROUP_ADMIN
)
)
@ -472,7 +470,7 @@ class core extends common
if ($this->getData(['page', $this->getUrl(0)]) !== null) {
if (
$this->getData(['page', $this->getUrl(0), 'group']) === common::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
or ($this->isConnected() === true
// and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * 10 + $this->getUser('profil')) >= ($this->getData(['page', $this->getUrl(0), 'group']) * 10 + $this->getData(['page', $this->getUrl(0), 'profil']))
@ -489,9 +487,9 @@ class core extends common
// Empêcher l'accès aux pages désactivées par URL directe
if (
($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) or ($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') < common::GROUP_EDITOR
)
) {
@ -505,6 +503,22 @@ class core extends common
) {
$access = false;
}
/** Empêche la consultation d'un espace laissé ouvert après la déconnexion et redirige vers home
* L'utilisateur n'est pas connecté
* ET l'accueil n'est pas affiché
* ET l'espace affiché nécessite un compte d'accès, enrolment vaut 1,2 ou 3
* */
if (
$this->isConnected() === false
and self::$siteContent !== 'home'
and $this->getData(['course', self::$siteContent, 'enrolment']) > 0
) {
$_SESSION['ZWII_SITE_CONTENT'] = 'home';
header(header: 'Location:' . helper::baseUrl(true) . 'swap/' . self::$siteContent);
exit();
}
}
/**
@ -538,10 +552,11 @@ class core extends common
}
// Accès concurrent stocke la page visitée
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
&& $this->getUser('id')
&& !$this->isPost()
) {
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()]);
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()], false);
$this->setData(['user', $this->getUser('id'), 'accessTimer', time()]);
}
// Breadcrumb
@ -658,7 +673,7 @@ class core extends common
// Check le groupe de l'utilisateur
if (
($module::$actions[$action] === common::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
or ($this->isConnected() === true
and $this->getUser('group') >= $module::$actions[$action]
and $this->getUser('permission', $moduleId, $action)
)

View File

@ -128,7 +128,17 @@ class SitemapGenerator
*/
private $sampleRobotsLines = [
"User-agent: *",
"Disallow: /",
"User-agent: Googlebot",
"Allow: /",
"User-agent: bingbot",
"Allow: /",
"User-agent: Slurp",
"Allow: /",
"User-agent: DuckDuckBot",
"Allow: /",
"User-agent: Baiduspider",
"Allow: /"
];
/**
* @var array list of valid changefreq values according to the spec

View File

@ -216,15 +216,16 @@ core.start = function () {
// Variables des cookies
var getUrl = window.location;
var domain = "domain=" + getUrl.hostname + ";";
var basePath = getUrl.pathname.substring(0, getUrl.pathname.lastIndexOf('/') + 1);
var path = "path=" + basePath + ";";
var e = new Date();
e.setFullYear(e.getFullYear() + 1);
var expires = "expires=" + e.toUTCString();
var expires = "expires=" + e.toUTCString() + ";";
// Stocke le cookie d'acceptation
document.cookie = "ZWII_COOKIE_CONSENT=true;samesite=strict;" + domain + expires;
document.cookie = "ZWII_COOKIE_CONSENT=true; samesite=lax; " + domain + path + expires;
});
/**
* Fermeture de la popup des cookies
*/

View File

@ -51,7 +51,7 @@ class common
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '1.11.02';
const ZWII_VERSION = '1.14.04';
// URL autoupdate
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/campus-update/raw/branch/master/';
@ -320,29 +320,58 @@ class common
public function __construct()
{
// Construct cache
if (isset($GLOBALS['common_construct'])) {
$this->input['_POST'] = $GLOBALS['common_construct']['input']['_POST'];
$this->input['_COOKIE'] = $GLOBALS['common_construct']['input']['_COOKIE'];
self::$siteContent = $GLOBALS['common_construct']['siteContent'];
$this->dataFiles = $GLOBALS['common_construct']['dataFiles'];
$this->configFiles = $GLOBALS['common_construct']['configFiles'];
$this->user = $GLOBALS['common_construct']['user'];
self::$i18nUI = $GLOBALS['common_construct']['i18nUI'];
$this->hierarchy = $GLOBALS['common_construct']['hierarchy'];
$this->url = $GLOBALS['common_construct']['url'];
self::$dialog = $GLOBALS['common_construct']['dialog'];
return;
}
// Extraction des données http
if (isset($_POST)) {
$this->input['_POST'] = $_POST;
// Cache
$GLOBALS['common_construct']['input']['_POST'] = $this->input['_POST'];
}
if (isset($_COOKIE)) {
$this->input['_COOKIE'] = $_COOKIE;
// Cache
$GLOBALS['common_construct']['input']['_COOKIE'] = $this->input['_COOKIE'];
}
// Déterminer le contenu du site
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
// Déterminé par la session présente
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT'];
} else {
$_SESSION['ZWII_SITE_CONTENT'] = 'home';
self::$siteContent = 'home';
}
// Cache
$GLOBALS['common_construct']['siteContent'] = self::$siteContent;
// Instanciation de la classe des entrées / sorties
// Les fichiers de configuration
foreach ($this->configFiles as $module => $value) {
$this->initDB($module);
}
// Cache
$GLOBALS['common_construct']['configFiles'] = $this->configFiles;
// Les fichiers des contenus
foreach ($this->contentFiles as $module => $value) {
$this->initDB($module, self::$siteContent);
}
// Cache
$GLOBALS['common_construct']['dataFiles'] = $this->dataFiles;
// Installation fraîche, initialisation de la configuration inexistante
// Nécessaire pour le constructeur
@ -368,6 +397,8 @@ class common
if ($this->user === []) {
$this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]);
}
// Cache
$GLOBALS['common_construct']['user'] = $this->user;
// Langue de l'administration si le user est connecté
if ($this->getData(['user', $this->getUser('id'), 'language'])) {
@ -390,13 +421,17 @@ class common
// Stocker le cookie de langue pour l'éditeur de texte ainsi que l'url du contenu pour le theme
setcookie('ZWII_UI', self::$i18nUI, time() + 3600, '', '', false, false);
// Stocker l'courseId pour le thème de TinyMCE
setcookie('ZWII_SITE_CONTENT', self::$siteContent, time() + 3600, '', '', false, false);
//setcookie('ZWII_SITE_CONTENT', self::$siteContent, time() + 3600, '', '', false, false);
setlocale(LC_ALL, self::$i18nUI);
// Cache
$GLOBALS['common_construct']['i18nUI'] = self::$i18nUI;
// Construit la liste des pages parents/enfants
if ($this->hierarchy['all'] === []) {
$this->buildHierarchy();
}
// Cache
$GLOBALS['common_construct']['hierarchy'] = $this->hierarchy;
// Construit l'url
if ($this->url === '') {
@ -406,6 +441,8 @@ class common
$this->url = $this->homePageId();
}
}
// Cache
$GLOBALS['common_construct']['url'] = $this->url;
// Chargement des dialogues
if (!file_exists(self::I18N_DIR . self::$i18nUI . '.json')) {
@ -425,6 +462,8 @@ class common
self::$dialog = array_merge(self::$dialog, $d);
}
}
// Cache
$GLOBALS['common_construct']['dialog'] = self::$dialog;
// Données de proxy
$proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']);
@ -448,12 +487,10 @@ class common
}
// Mise à jour des données core
include ('core/include/update.inc.php');
include('core/include/update.inc.php');
}
/**
* Ajoute les valeurs en sortie
* @param array $output Valeurs en sortie
@ -513,8 +550,10 @@ class common
/**
* Sauvegarde des données
* @param array $keys Clé(s) des données
* @param bool $save Indique si le fichier doit être sauvegardé après modification (par défaut true)
* @return bool Succès de l'opération
*/
public function setData($keys = [])
public function setData($keys = [], $save = true)
{
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
if (
@ -542,11 +581,12 @@ class common
$query .= '.' . $keys[$i];
}
// Appliquer la modification, le dernier élément étant la donnée à sauvegarder
$success = is_object($db->set($query, $keys[count($keys) - 1], true));
$success = is_object($db->set($query, $keys[count($keys) - 1], $save));
}
return $success;
}
/**
* Accède aux données
* @param array $keys Clé(s) des données
@ -590,7 +630,7 @@ class common
/**
* Ecrire les données de la page
* @param string pageId
* @param string contenu de la page
* @param array contenu de la page
* @return int nombre d'octets écrits ou erreur
*/
public function setPage($page, $value, $path)
@ -616,7 +656,7 @@ class common
* Écrit les données dans un fichier avec plusieurs tentatives d'écriture et verrouillage
*
* @param string $filename Le nom du fichier
* @param array $data Les données à écrire dans le fichier
* @param string $data Les données à écrire dans le fichier
* @param int $flags Les drapeaux optionnels à passer à la fonction $this->secure_file_put_contents
* @return bool True si l'écriture a réussi, sinon false
*/
@ -626,45 +666,60 @@ class common
// Initialise le compteur de tentatives
$attempts = 0;
// Convertit les données en chaîne de caractères
$serialized_data = serialize($data);
// Vérifie la longueur des données
$data_length = strlen($serialized_data);
$data_length = strlen($data);
// Effectue jusqu'à 5 tentatives d'écriture
while ($attempts < 5) {
// Essaye d'écrire les données dans le fichier avec verrouillage exclusif
$write_result = file_put_contents($filename, $data, LOCK_EX | $flags);
// $now = \DateTime::createFromFormat('U.u', microtime(true));
// file_put_contents("tmplog.txt", '[SecurePut][' . $now->format('H:i:s.u') . ']' . "\r\n", FILE_APPEND);
// Vérifie si l'écriture a réussi
if ($write_result !== false && $write_result === $data_length) {
// Sort de la boucle si l'écriture a réussi
return true;
break;
}
// Incrémente le compteur de tentatives
$attempts++;
sleep(1);
}
// Échec de l'écriture après plusieurs tentatives
return false;
// Etat de l'écriture
return ($attempts < 5);
}
public function initDB($module, $path = '')
{
// Instanciation de la classe des entrées / sorties
// Constructeur JsonDB;
$this->dataFiles[$module] = new \Prowebcraft\JsonDb([
// Chemin complet vers le fichier JSON
$dir = empty($path) ? self::DATA_DIR : self::DATA_DIR . $path . '/';
$config = [
'name' => $module . '.json',
'dir' => empty($path) ? self::DATA_DIR : self::DATA_DIR . $path . '/',
'backup' => file_exists('site/data/.backup')
]);
'dir' => $dir,
'backup' => file_exists('site/data/.backup'),
'update' => false,
];
// Instanciation de l'objet et stockage dans dataFiles
$this->dataFiles[$module] = new \Prowebcraft\JsonDb($config);
}
/**
* Cette fonction est liée à saveData
* @param mixed $module
* @return void
*/
public function saveDB($module): void
{
$db = $this->dataFiles[$module];
$db->save();
}
/**
* Initialisation des données sur un contenu ou la page d'accueil
* @param string $course : id du module à générer
@ -676,7 +731,7 @@ class common
{
// Tableau avec les données vierges
require_once ('core/module/install/ressource/defaultdata.php');
require_once('core/module/install/ressource/defaultdata.php');
// L'arborescence
if (!file_exists(self::DATA_DIR . $path)) {
@ -711,7 +766,7 @@ class common
public function saveConfig($module)
{
// Tableau avec les données vierges
require_once ('core/module/install/ressource/defaultdata.php');
require_once('core/module/install/ressource/defaultdata.php');
// Installation des données des autres modules cad theme profil font config, admin et core
$this->setData([$module, init::$defaultData[$module]]);
common::$coreNotices[] = $module;
@ -758,7 +813,7 @@ class common
$this->getData(['page', $pageId, 'parentPageId']) === ""
// Ignore les pages dont l'utilisateur n'a pas accès
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
or ($this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY')
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
@ -789,7 +844,7 @@ class common
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
)
or (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY')
and
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])
@ -1015,6 +1070,17 @@ class common
}
}
/**
* @return bool l'utilisateur est connecté true sinon false
*/
public function isConnected()
{
return (
!empty($this->getUser('authKey'))
&&
$this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY'));
}
/**
* Check qu'une valeur est transmise par la méthode _POST
* @return bool

View File

@ -2,7 +2,7 @@
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>

View File

@ -2,7 +2,7 @@
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr_FR">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;">
<meta name="viewport" content="width=device-width">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="x-apple-disable-message-reformatting">

View File

@ -2,7 +2,7 @@
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;">
<meta meta="description=" content="ZwiiCMS le CMS multilingue sans base de données">
<meta name="generator" content="ZiiCMS https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS">
<meta name="viewport" content="width=device-width, initial-scale=1">
@ -47,7 +47,7 @@
if (
$this->getData(['theme', 'menu', 'position']) === 'top'
and $this->getData(['theme', 'menu', 'fixed']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') > self::GROUP_MEMBER
) {
echo '<nav id="navfixedconnected" >';

View File

@ -22,7 +22,7 @@ class config extends common
'copyBackups' => self::GROUP_ADMIN,
'delBackups' => self::GROUP_ADMIN,
'configMetaImage' => self::GROUP_ADMIN,
'siteMap' => self::GROUP_ADMIN,
'sitemap' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN,
@ -30,7 +30,8 @@ class config extends common
'logReset' => self::GROUP_ADMIN,
'logDownload' => self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN
'blacklistDownload' => self::GROUP_ADMIN,
'register' => self::GROUP_ADMIN,
];
public static $timezones = [
@ -213,7 +214,7 @@ class config extends common
* Sitemap compressé et non compressé
* Robots.txt
*/
public function siteMap()
public function sitemap()
{
// La page n'existe pas
if (
@ -592,7 +593,7 @@ class config extends common
}
}
// Générer robots.txt et sitemap
$this->siteMap();
$this->sitemap();
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
@ -972,4 +973,25 @@ class config extends common
return getenv('HTTP_MOD_REWRITE') == 'On' || getenv('REDIRECT_STATUS') == '200';
}
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'config' => $this->getUrl(2),
'page' => $this->getData(['user', $this->getUser('id'), 'view', 'page']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config/' . $this->getUrl(2),
]);
}
}

View File

@ -66,11 +66,12 @@ $(document).ready(function () {
$("#connectCaptchaStrong").prop("checked", false);
}
var configLayout = getCookie("configLayout");
if (configLayout == null) {
configLayout = "locale";
setCookie("configLayout", "locale");
}
var configLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'config']);?>";
// Non défini, valeur par défaut
if (configLayout == "") {
configLayout = "setup";
}
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
@ -168,7 +169,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "locale");
});
$("#configSetupButton").on("click", function () {
$("#localeContainer").hide();
@ -181,7 +181,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "setup");
});
$("#configSocialButton").on("click", function () {
@ -195,7 +194,6 @@ $(document).ready(function () {
$("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "social");
});
$("#configConnectButton").on("click", function () {
$("#setupContainer").hide();
@ -208,7 +206,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "connect");
});
$("#configNetworkButton").on("click", function () {
$("#setupContainer").hide();
@ -221,7 +218,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton");
setCookie("configLayout", "network");
});
@ -308,27 +304,6 @@ $(document).ready(function () {
});
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -7,44 +7,35 @@
'value' => template::ico('home')
]); ?>
</div>
<div class="col1">
<?php /**echo template::button('configHelp', [
'class' => 'buttonHelp',
'href' => 'https://doc.zwiicms.fr/configuration-du-site',
'target' => '_blank',
'value' => template::ico('help'),
'help' => 'Consulter l\'aide en ligne'
]); */?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('Submit'); ?>
</div>
</div>
<div class="tab">
<?php echo template::button('configLocaleButton', [
'value' => 'Identité - Étiquettes',
'class' => 'buttonTab'
]); ?>
<?php echo template::button('configSetupButton', [
'value' => 'Configuration - Outils',
'class' => 'buttonTab'
'value' => 'Configuration',
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/setup'
]); ?>
<?php echo template::button('configSocialButton', [
'value' => 'Réseaux sociaux',
'class' => 'buttonTab'
'value' => 'Référencement',
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/social'
]); ?>
<?php echo template::button('configConnectButton', [
'value' => 'Sécurité',
'class' => 'buttonTab'
'value' => 'Connexion',
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/connect'
]); ?>
<?php echo template::button('configNetworkButton', [
'value' => 'Réseau',
'class' => 'buttonTab'
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/network'
]); ?>
</div>
<?php include('core/module/config/view/locale/locale.php') ?>
<?php include('core/module/config/view/setup/setup.php') ?>

View File

@ -669,17 +669,12 @@ class course extends common
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
$sumPages = 0;
$pages = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
$pages = $pages['page'];
foreach ($pages as $pageId => $pageData) {
if ($pageData['position'] > 0) {
$sumPages++;
}
}
$sumPages = $this->countPages($pages['page']);
// Liste des inscrits dans le contenu sélectionné.
$users = $this->getData(['enrolment', $courseId]);
// Obtient les statistiques de l'ensemble de la cohorte
$reports = $this->getReport($courseId);
if (is_array($users)) {
@ -798,9 +793,11 @@ class course extends common
$this->getData(['user', $keyPost]) !== null
&& $this->getData(['enrolment', $courseId, $keyPost]) === null
) {
$this->setData(['enrolment', $courseId, $keyPost, 'history', array()]);
$this->setData(['enrolment', $courseId, $keyPost, 'history', array()], false);
}
}
// Sauvegarde la base manuellement
$this->saveDB('enrolment');
}
// Liste des groupes et des profils
@ -1154,11 +1151,6 @@ class course extends common
? helper::baseUrl() . $this->getData(['enrolment', $courseId, $userId, 'lastPageView'])
: helper::baseUrl();
/*
$essage = $this->getData(['enrolment', $courseId, $userId, 'datePageView'])
? $this->getData(['enrolment', $courseId, $userId, 'datePageView'])
: '';
*/
if ($this->getData(['course', $courseId, 'access']) === self::COURSE_ACCESS_DATE) {
$to = helper::dateUTF8('%d %B %Y', $this->getData(['course', $courseId, 'closingDate']), self::$i18nUI) . helper::translate(' à ') . helper::dateUTF8('%H:%M', $this->getData(['course', $courseId, 'closingDate']), self::$i18nUI);
$message .= sprintf(helper::translate('Ce contenu ferme le %s'), $to);
@ -1390,7 +1382,7 @@ class course extends common
if (!empty($userValue['history'])) {
$maxTime = max($userValue['history']);
$lastPageId = array_search($maxTime, $userValue['history']);
$this->setData(['enrolment', $courseId, $userId, 'lastPageView', $lastPageId]);
$this->setData(['enrolment', $courseId, $userId, 'lastPageView', $lastPageId], false);
$this->setData(['enrolment', $courseId, $userId, 'datePageView', $maxTime]);
}
}
@ -2027,7 +2019,7 @@ class course extends common
/**
* Autorise l'accès à un contenu
* @param @return bool le user a le droit d'entrée dans le contenu
* @return bool le user a le droit d'entrée dans le contenu
* @param string $courseId identifiant du contenu sollicité
*/
public function courseIsAvailable($courseId)
@ -2038,7 +2030,7 @@ class course extends common
}
// Si un utilisateur connecté est admin ou auteur, c'est autorisé
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') &&
$this->isConnected() === true &&
($this->getUser('group') === self::GROUP_ADMIN ||
$this->getUser('id') === $this->getData(['course', $courseId, 'author']))
) {
@ -2055,17 +2047,23 @@ class course extends common
time() <= $this->getData(['course', $courseId, 'closingDate'])
);
case self::COURSE_ACCESS_CLOSE:
default:
return false;
}
}
/**
*
* Compte les pages d'un espace
* @param mixed $array Tableau des pages de l'espace
* @return int Nombre de pages
*/
private function countPages($array)
{
$count = 0;
foreach ($array as $key => $value) {
$count++; // Incrémente le compteur pour chaque clé associative trouvée
if (is_array($value)) {
$count += $this->countPages($value); // Appelle récursivement la fonction si la valeur est un tableau
foreach ($array as $pageId => $pageData) {
if ($pageData['position'] > 0) {
$count++;
}
}
return $count;
@ -2085,7 +2083,7 @@ class course extends common
/**
* Autorise l'accès à un contenu
* @param @return bool le user a le droit d'entrée dans le contenu
* @return bool le user a le droit d'entrée dans le contenu
* @param string $userId identifiant de l'utilisateur
* @param string $courseId identifiant du contenu sollicité
*/
@ -2118,7 +2116,7 @@ class course extends common
/**
* Lit le contenu des fichiers de traces au format CS et renvoie un tableau associatif
*/
private function getReport($courseId, $userId = null)
public function getReport($courseId, $userId = null)
{
$data = [];
@ -2134,14 +2132,19 @@ class course extends common
$pageId = $line[1];
$timestamp = $line[2];
// Filtre userId
// if (!is_null($userId) && $name === $userId) {
if (
is_null($userId) === false
&& $name !== $userId
) {
continue;
}
// Initialiser le tableau si nécessaire
if (!isset($data[$name][$pageId])) {
$data[$name][$pageId] = array();
}
// Ajouter le timestamp
$data[$name][$pageId][] = $timestamp;
//}
}
// Fermer le fichier
@ -2158,6 +2161,4 @@ class course extends common
// Afficher le JSON;
return $data;
}
}

View File

@ -8,7 +8,7 @@
</div>
<div class="col1 offset10">
<?php echo template::button('userDeleteAll', [
'href' => helper::baseUrl() . 'course/userHistoryExport/' . $this->getUrl(2) . '/' . $this->getUrl(3),
'href' => helper::baseUrl() . 'course/userReportExport/' . $this->getUrl(2) . '/' . $this->getUrl(3),
'value' => template::ico('download'),
'help' => 'Exporter',
]) ?>

View File

@ -8,7 +8,7 @@
</div>
<div class="col1 offset8">
<?php echo template::button('userDeleteAll', [
'href' => helper::baseUrl() . 'course/usersHistoryExport/' . $this->getUrl(2),
'href' => helper::baseUrl() . 'course/usersReportExport/' . $this->getUrl(2),
'value' => template::ico('download'),
'help' => 'Exporter',
]) ?>

View File

@ -158,9 +158,9 @@ class install extends common
);
// Sauvegarder la configuration du Proxy
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')]);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')], false);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')], false);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)], false);
// Images exemples livrées dans tous les cas
try {
@ -203,7 +203,7 @@ class install extends common
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])], false);
// Valeurs en sortie
$this->addOutput([
@ -212,9 +212,10 @@ class install extends common
'state' => true
]);
}
// Force la sauvegarde
$this->saveDB('config');
// Affichage du formulaire
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,

View File

@ -246,7 +246,7 @@ class init extends common
'manage' => false,
'users' => false,
'userHistory' => false,
'userHistoryExport' => false,
'userReportExport' => false,
'usersAdd' => false,
'userDelete' => false,
'usersDelete' => false,
@ -343,7 +343,7 @@ class init extends common
'manage' => false,
'users' => false,
'userHistory' => false,
'userHistoryExport' => false,
'userReportExport' => false,
'usersAdd' => false,
'userDelete' => false,
'usersDelete' => false,
@ -445,7 +445,7 @@ class init extends common
'manage' => true,
'users' => true,
'userHistory' => true,
'userHistoryExport' => true,
'userReportExport' => true,
'usersAdd' => true,
'userDelete' => false,
'usersDelete' => false,
@ -543,7 +543,7 @@ class init extends common
'manage' => true,
'users' => true,
'userHistory' => true,
'userHistoryExport' => true,
'userReportExport' => true,
'usersAdd' => true,
'userDelete' => true,
'usersDelete' => true,

View File

@ -23,7 +23,8 @@ class page extends common
'edit' => self::GROUP_EDITOR,
'duplicate' => self::GROUP_EDITOR,
'jsEditor' => self::GROUP_EDITOR,
'cssEditor' => self::GROUP_EDITOR
'cssEditor' => self::GROUP_EDITOR,
'register' => self::GROUP_EDITOR,
];
public static $pagesNoParentId = [
'' => 'Aucune'
@ -118,14 +119,16 @@ class page extends common
$page
]);
// Ecriture
$this->setData(['page', $pageId, $data]);
$this->setData(['page', $pageId, $data], false);
$notification = helper::translate('Page dupliquée');
// Duplication du module présent
if ($this->getData(['page', $page, 'moduleId'])) {
$data = $this->getData(['module', $page]);
$this->setData(['module', $pageId, $data]);
$this->setData(['module', $pageId, $data], false);
$notification = helper::translate('Page et module dupliqués');
}
// Force la sauvegarde
$this->saveDB('page');
// Valeurs en sortie
$this->addOutput([
@ -390,11 +393,11 @@ class page extends common
$pageId = helper::increment($pageId, self::$moduleIds);
// Met à jour les enfants
foreach ($this->getHierarchy($this->getUrl(2), null) as $childrenPageId) {
$this->setData(['page', $childrenPageId, 'parentPageId', $pageId]);
$this->setData(['page', $childrenPageId, 'parentPageId', $pageId], false);
}
// Change l'id de page dans les données des modules
if ($this->getData(['module', $this->getUrl(2)]) !== null) {
$this->setData(['module', $pageId, $this->getData(['module', $this->getUrl(2)])]);
$this->setData(['module', $pageId, $this->getData(['module', $this->getUrl(2)])], false);
$this->deleteData(['module', $this->getUrl(2)]);
// Renommer le dossier du module
$moduleId = $this->getData(['page', $this->getUrl(2), 'moduleId']);
@ -405,8 +408,10 @@ class page extends common
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
// Mettre à jour le nom de la feuille de style
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId]);
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId], false);
}
// Sauvegarde la base manuellement
$this->saveDB('module');
}
// Met à jour les historiques des utilisateurs
foreach ($this->getData(['enrolment', self::$siteContent]) as $userId => $userData) {
@ -417,14 +422,17 @@ class page extends common
) {
// Remplacer l'ancienne ID par la nouvelle
$datas = $this->getData(['enrolment', self::$siteContent, $userId, 'history', $this->getUrl(2)]);
$this->setData(['enrolment', self::$siteContent, $userId, 'history', $pageId, $datas]);
$this->setData(['enrolment', self::$siteContent, $userId, 'history', $pageId, $datas], false);
$this->deleteData(['enrolment', self::$siteContent, $userId, 'history', $this->getUrl(2)]);
}
// Mettre à jour la dernière page vue si nécessaire
if ($this->getData(['enrolment', self::$siteContent, $userId, 'lastPageView']) === $this->getUrl(2)) {
$this->setData(['enrolment', self::$siteContent, $userId, 'lastPageView', $pageId]);
$this->setData(['enrolment', self::$siteContent, $userId, 'lastPageView', $pageId], false);
}
}
// Sauvegarde la base manuellement
$this->saveDB('enrolment');
// Met à jour la homePage si nécessaire
if ($this->getUrl(2) === $this->getData(['course', self::$siteContent, 'homePageId'])) {
$this->setData(['course', self::$siteContent, 'homePageId', $pageId]);
@ -432,7 +440,7 @@ class page extends common
// Si la page correspond à la page d'accueil, change l'id dans la configuration du site
if ($this->getData(['config', 'homePageId']) === $this->getUrl(2)) {
$this->setData(['config', 'homePageId', $pageId]);
$this->setData(['config', 'homePageId', $pageId], false);
}
}
// Supprime les données du module en cas de changement de module
@ -448,20 +456,22 @@ class page extends common
}
// Traitement des pages spéciales affectées dans la config :
if ($this->getUrl(2) === $this->getData(['config', 'legalPageId'])) {
$this->setData(['config', 'legalPageId', $pageId]);
$this->setData(['config', 'legalPageId', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['config', 'searchPageId'])) {
$this->setData(['config', 'searchPageId', $pageId]);
$this->setData(['config', 'searchPageId', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['config', 'page404'])) {
$this->setData(['config', 'page404', $pageId]);
$this->setData(['config', 'page404', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['config', 'page403'])) {
$this->setData(['config', 'page403', $pageId]);
$this->setData(['config', 'page403', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['config', 'page302'])) {
$this->setData(['config', 'page302', $pageId]);
$this->setData(['config', 'page302', $pageId], false);
}
// Sauvegarde la base manuellement
$this->saveDB(module: 'config');
// 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());
@ -480,11 +490,12 @@ class page extends common
$lastPosition++;
}
// Change la position
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition]);
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition], false);
// Incrémente pour la prochaine position
$lastPosition++;
}
}
if ($this->getinput('pageEditBlock') !== 'bar') {
$barLeft = $this->getinput('pageEditBarLeft');
$barRight = $this->getinput('pageEditBarRight');
@ -505,7 +516,7 @@ class page extends common
) {
foreach ($this->getHierarchy($pageId) as $parentId => $childId) {
if ($this->getData(['page', $childId, 'parentPageId']) === $pageId) {
$this->setData(['page', $childId, 'position', 0]);
$this->setData(['page', $childId, 'position', 0], false);
}
}
}
@ -514,17 +525,17 @@ class page extends common
if ($this->getinput('pageEditBlock') === 'bar') {
foreach ($this->getHierarchy() as $eachPageId => $parentId) {
if ($this->getData(['page', $eachPageId, 'barRight']) === $this->getUrl(2)) {
$this->setData(['page', $eachPageId, 'barRight', $pageId]);
$this->setData(['page', $eachPageId, 'barRight', $pageId], false);
}
if ($this->getData(['page', $eachPageId, 'barLeft']) === $this->getUrl(2)) {
$this->setData(['page', $eachPageId, 'barLeft', $pageId]);
$this->setData(['page', $eachPageId, 'barLeft', $pageId], false);
}
foreach ($parentId as $childId) {
if ($this->getData(['page', $childId, 'barRight']) === $this->getUrl(2)) {
$this->setData(['page', $childId, 'barRight', $pageId]);
$this->setData(['page', $childId, 'barRight', $pageId], false);
}
if ($this->getData(['page', $childId, 'barLeft']) === $this->getUrl(2)) {
$this->setData(['page', $childId, 'barLeft', $pageId]);
$this->setData(['page', $childId, 'barLeft', $pageId], false);
}
}
}
@ -740,10 +751,31 @@ class page extends common
{
$p = $this->getData(['page']);
$d = array_map(function ($d) {
unset ($d["css"], $d["js"]);
unset($d["css"], $d["js"]);
return $d;
}, $p);
return json_encode($d);
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'page' => $this->getUrl(2),
'config' => $this->getData(['user', $this->getUser('id'), 'view', 'config']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(3) . '/' . self::$siteContent,
]);
}
}

View File

@ -67,16 +67,18 @@ $( document ).ready(function() {
/**
* Sélection des onglets
*/
var pageLayout = getCookie("pageLayout");
if (pageLayout == null) {
pageLayout = "content";
setCookie("pageLayout", "content");
var pageLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'page']);?>";
// Non défini, valeur par défaut
if (pageLayout == "") {
pageLayout = "content";
}
// Tout cacher
$("#pageEditContentContainer").hide();
$("#pageEditExtensionContainer").hide();
$("#pageEditPositionContainer").hide();
$("#pageEditLayoutContainer").hide();
$("#pageEditPermissionContainer").hide();
// Afficher la bonne tab
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Container").show();
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Button").addClass("activeButton");
@ -295,7 +297,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "content");
});
$("#pageEditExtensionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -308,7 +309,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "extension");
});
$("#PageEditPositionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -321,7 +321,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").addClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "position");
});
$("#pageEditLayoutButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -334,7 +333,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").addClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "layout");
});
$("#pageEditPermissionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -347,7 +345,6 @@ $( document ).ready(function() {
$("#pageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").addClass("activeButton");
setCookie("pageLayout", "permission");
});
/**
@ -722,30 +719,6 @@ function buildPagesList(extraPosition) {
positionDOM.val(positionSelected);
};
/**
* Cookies
*/
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -1,4 +1,6 @@
<?php echo template::formOpen('pageEditForm'); ?>
<!-- Variable transmise à TinyMCE -->
<div id="zwii_site_content" data-variable="<?php echo htmlspecialchars(isset($_SESSION['ZWII_SITE_CONTENT']) ? $_SESSION['ZWII_SITE_CONTENT'] : 'home'); ?>"></div>
<div class="row">
<div class="col1">
<?php echo template::button('configModulesBack', [
@ -28,26 +30,32 @@
]); ?>
</div>
</div>
<div class="tab">
<?php echo template::button('pageEditContentButton', [
'value' => 'Contenu',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/content/' . $this->geturl(2)
]); ?>
<?php echo template::button('PageEditPositionButton', [
<?php echo template::button('pageEditPositionButton', [
'value' => 'Menu',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/position/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditExtensionButton', [
'value' => 'Extension',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/extension/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditLayoutButton', [
'value' => 'Mise en page',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/layout/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditPermissionButton', [
'value' => 'Permission',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/permission/' . $this->geturl(2)
]); ?>
</div>

View File

@ -25,7 +25,7 @@ class plugin extends common
'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN,
//'item' => self::GROUP_ADMIN,
// détail d'un objet
'upload' => self::GROUP_ADMIN,
// Téléverser catalogue
@ -237,8 +237,8 @@ class plugin extends common
return ([
'success' => $success,
'notification' => $success
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
: helper::translate('Erreur inconnue, le module n\'est pas installé')
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
: helper::translate('Erreur inconnue, le module n\'est pas installé')
]);
} else {
// Supprimer le dossier temporaire
@ -391,7 +391,6 @@ class plugin extends common
];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Catalogue de modules'),
@ -414,6 +413,16 @@ class plugin extends common
]);
}
/**
* Retourne le contenu du store en ligne
* @return mixed
*/
public static function getStore()
{
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
return $store;
}
/**
* Gestion des modules
*/
@ -561,6 +570,9 @@ class plugin extends common
}
}
// Désactive l'icône rouge
$this->setData(['core', 'updateModuleAvailable', false]);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Gestion des modules'),

View File

@ -507,21 +507,23 @@ class theme extends common
'featureContent' => $featureContent,
'featureFiles' => $files
]
]);
], false);
// Modification de la position du menu selon la position de la bannière
if ($this->getData(['theme', 'header', 'position']) == 'site') {
$this->setData(['theme', 'menu', 'position', str_replace('body-', 'site-', $this->getData(['theme', 'menu', 'position']))]);
$this->setData(['theme', 'menu', 'position', str_replace('body-', 'site-', $this->getData(['theme', 'menu', 'position']))], false);
}
if ($this->getData(['theme', 'header', 'position']) == 'body') {
$this->setData(['theme', 'menu', 'position', str_replace('site-', 'body-', $this->getData(['theme', 'menu', 'position']))]);
$this->setData(['theme', 'menu', 'position', str_replace('site-', 'body-', $this->getData(['theme', 'menu', 'position']))], false);
}
// Menu accroché à la bannière qui devient cachée
if (
$this->getData(['theme', 'header', 'position']) == 'hide' &&
in_array($this->getData(['theme', 'menu', 'position']), ['body-first', 'site-first', 'body-first', 'site-second'])
) {
$this->setData(['theme', 'menu', 'position', 'site']);
$this->setData(['theme', 'menu', 'position', 'site'], false);
}
// Sauvegarde la base manuellement
$this->saveDB(module: 'theme');
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
@ -636,11 +638,11 @@ class theme extends common
// Polices liées aux thèmes des espaces
foreach ($this->getData(['course']) as $courseId => $courseValue) {
$theme = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/theme.json'), true);
$fonts['Bannière ('. $courseId .')'] = $theme['theme']['header']['font'];
$fonts['Menu ('. $courseId .')'] = $theme['theme']['menu']['font'];
$fonts['Titre ('. $courseId .')'] = $theme['theme']['title']['font'];
$fonts['Texte ('. $courseId .')'] = $theme['theme']['text']['font'];
$fonts['Pied de page ('. $courseId .')'] = $theme['theme']['footer']['font'];
$fonts['Bannière (' . $courseId . ')'] = $theme['theme']['header']['font'];
$fonts['Menu (' . $courseId . ')'] = $theme['theme']['menu']['font'];
$fonts['Titre (' . $courseId . ')'] = $theme['theme']['title']['font'];
$fonts['Texte (' . $courseId . ')'] = $theme['theme']['text']['font'];
$fonts['Pied de page (' . $courseId . ')'] = $theme['theme']['footer']['font'];
}
// Récupérer le détail des fontes installées
@ -658,7 +660,7 @@ class theme extends common
if (is_array($typeValue)) {
foreach ($typeValue as $fontId => $fontValue) {
// Recherche les correspondances
$result = array_filter($fonts, function($value) use ($fontId) {
$result = array_filter($fonts, function ($value) use ($fontId) {
return $value == $fontId;
});
$keyResults = array_keys($result);
@ -929,7 +931,7 @@ class theme extends common
'fontWeight' => $this->getInput('themeTitleFontWeight'),
'textTransform' => $this->getInput('themeTitleTextTransform')
]
]);
], false);
$this->setData([
'theme',
'text',
@ -939,7 +941,7 @@ class theme extends common
'textColor' => $this->getInput('themeTextTextColor'),
'linkColor' => $this->getInput('themeTextLinkColor')
]
]);
], false);
$this->setData([
'theme',
'site',
@ -950,14 +952,14 @@ class theme extends common
'width' => $this->getInput('themeSiteWidth'),
'margin' => $this->getInput('themeSiteMargin', helper::FILTER_BOOLEAN)
]
]);
], false);
$this->setData([
'theme',
'button',
[
'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
]
]);
], false);
$this->setData([
'theme',
'block',

View File

@ -428,7 +428,9 @@ class user extends common
if ($this->getUser('group') < self::GROUP_ADMIN) {
if ($this->getInput('userEditNewPassword')) {
// L'ancien mot de passe est correct
if (password_verify(html_entity_decode($this->getInput('userEditOldPassword')), $this->getData(['user', $this->getUrl(2), 'password']))) {
if (
password_verify(html_entity_decode($this->getInput('userEditOldPassword')), $this->getData(['user', $this->getUrl(2), 'password']))
) {
// La confirmation correspond au mot de passe
if ($this->getInput('userEditNewPassword') === $this->getInput('userEditConfirmPassword')) {
$newPassword = $this->getInput('userEditNewPassword', helper::FILTER_PASSWORD, true);
@ -502,6 +504,7 @@ class user extends common
'files' => $this->getInput('userEditFiles', helper::FILTER_BOOLEAN),
'language' => $this->getInput('userEditLanguage', helper::FILTER_STRING_SHORT),
'tags' => $this->getInput('userEditTags', helper::FILTER_STRING_SHORT),
'authKey' => $this->getData(['user', $this->getUrl(2), 'authKey']),
]
]);
// Redirection spécifique si l'utilisateur change son mot de passe
@ -572,7 +575,7 @@ class user extends common
// Enregistre la date de la demande dans le compte utilisateur
$this->setData(['user', $userId, 'forgot', time()]);
// Crée un id unique pour la réinitialisation
$uniqId = md5(json_encode($this->getData(['user', $userId])));
$uniqId = md5(json_encode($this->getData(['user', $userId, 'forgot'])));
// Envoi le mail
$sent = $this->sendMail(
$this->getData(['user', $userId, 'mail']),
@ -895,7 +898,7 @@ class user extends common
// Droits spécifiques
'users' => $this->getInput('profilEditCourseUsers', helper::FILTER_BOOLEAN),
'userHistory' => $this->getInput('profilEditCourseUserHistory', helper::FILTER_BOOLEAN),
'userHistoryExport' => $this->getInput('profilEditCourseUserHistoryExport', helper::FILTER_BOOLEAN),
'userReportExport' => $this->getInput('profilEditCourseuserReportExport', helper::FILTER_BOOLEAN),
'export' => $this->getInput('profilEditCourseExport', helper::FILTER_BOOLEAN),
'userAdd' => $this->getInput('profilEditCourseUserAdd', helper::FILTER_BOOLEAN),
'usersAdd' => $this->getInput('profilEditCourseUsersAdd', helper::FILTER_BOOLEAN),
@ -1092,7 +1095,7 @@ class user extends common
// La suite
'users' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN),
'userHistory' => $this->getInput('profilAddCourseUserHistory', helper::FILTER_BOOLEAN),
'userHistoryExport' => $this->getInput('profilAddCourseUserHistoryExport', helper::FILTER_BOOLEAN),
'userReportExport' => $this->getInput('profilAddCourseuserReportExport', helper::FILTER_BOOLEAN),
'export' => $this->getInput('profilAddCourseExport', helper::FILTER_BOOLEAN),
'userAdd' => $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN),
'usersAdd' => $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN),
@ -1147,12 +1150,12 @@ class user extends common
// Exclure les espaces des cours
/*
foreach (array_keys($this->getData(['course'])) as $courseId) {
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
return strpos($key, $courseId) === false;
});
}
*/
foreach (array_keys($this->getData(['course'])) as $courseId) {
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
return strpos($key, $courseId) === false;
});
}
*/
self::$sharePath = array_flip(self::$sharePath);
self::$sharePath = array_merge(['none' => 'Aucun Accès'], self::$sharePath);
@ -1259,7 +1262,7 @@ class user extends common
'lastFail' => time(),
'ip' => helper::getIp()
]
]);
], false);
// Verrouillage des IP
$ipBlackList = helper::arrayColumn($this->getData(['blacklist']), 'ip');
if (
@ -1288,8 +1291,8 @@ class user extends common
$this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
and $this->getData(['user', $userId, 'connectFail']) === $this->getData(['config', 'connect', 'attempt'])
) {
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
}
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
// Vérification du mot de passe et du groupe
@ -1301,8 +1304,12 @@ class user extends common
and $captcha === true
) {
// RAZ
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
// Clé d'authenfication
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
$this->setData(['user', $userId, 'authKey', $authKey], false);
// Validité du cookie
$expire = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? strtotime("+1 year") : 0;
@ -1310,17 +1317,23 @@ class user extends common
case false:
// Cookie de session
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_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
// Connexion par clé
setcookie('ZWII_AUTH_KEY', $authKey, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
break;
default:
// Cookie persistant
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false));
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
//setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
// Connexion par clé
setcookie('ZWII_AUTH_KEY', $authKey, $expire, helper::baseUrl(false, false));
break;
}
// Accès multiples avec le même compte
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']]);
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']], false);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if (
$this->getData(['config', 'maintenance'])
@ -1354,11 +1367,11 @@ class user extends common
$logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha';
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
if ($this->getData(['user', $userId, 'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1]);
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1], false);
}
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
if ($this->getdata(['user', $userId, 'connectFail']) == $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectTimeout', time()]);
$this->setData(['user', $userId, 'connectTimeout', time()], false);
}
// Cas 3 le délai de bloquage court
if ($this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time()) {
@ -1371,7 +1384,10 @@ class user extends common
]);
}
}
// Sauvegarde la base manuellement
$this->saveDB(module: 'user');
}
// Journalisation
$this->saveLog($logStatus);
@ -1394,7 +1410,8 @@ class user extends common
public function logout()
{
helper::deleteCookie('ZWII_USER_ID');
helper::deleteCookie('ZWII_USER_PASSWORD');
//helper::deleteCookie('ZWII_USER_PASSWORD');
helper::deleteCookie('ZWII_AUTH_KEY');
// Détruit la session
session_destroy();
@ -1419,13 +1436,29 @@ class user extends common
// Lien de réinitialisation trop vieux
or $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time()
// Id unique incorrecte
or $this->getUrl(3) !== md5(json_encode($this->getData(['user', $this->getUrl(2)])))
or $this->getUrl(3) !== md5(json_encode($this->getData(['user', $this->getUrl(2), 'forgot'])))
) {
$this->saveLog(
' Erreur de réinitialisation de mot de passe ' . $this->getUrl(2) .
' Compte : ' . $this->getData(['user', $this->getUrl(2)]) .
' Temps : ' . $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time() .
' Clé : ' . $this->getUrl(3) !== md5(json_encode($this->getData(['user', $this->getUrl(2), 'forgot'])))
);
// Message d'erreur en cas de problème de réinitialisation de mot de passe
$message = $this->getData(['user', $this->getUrl(2)]) === null
? ' Utilisateur inconnu '
: '';
$message = $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time()
? ' Temps dépassé '
: $message;
$message = $this->getUrl(3) !== md5(json_encode($this->getData(['user', $this->getUrl(2)])))
? ' Clé invalide '
: $message;
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseurl(),
'notification' => helper::translate('Impossible de réinitialiser le mot de passe de ce compte !'),
'notification' => helper::translate('Impossible de réinitialiser le mot de passe de ce compte !') . $message,
'state' => false
//'access' => false
]);
@ -1448,12 +1481,14 @@ class user extends common
$newPassword = $this->getInput('userResetNewPassword', helper::FILTER_PASSWORD, true);
}
// Modifie le mot de passe
$this->setData(['user', $this->getUrl(2), 'password', $newPassword]);
$this->setData(['user', $this->getUrl(2), 'password', $newPassword], false);
// Réinitialise la date de la demande
$this->setData(['user', $this->getUrl(2), 'forgot', 0]);
$this->setData(['user', $this->getUrl(2), 'forgot', 0], false);
// Réinitialise le blocage
$this->setData(['user', $this->getUrl(2), 'connectFail', 0]);
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0]);
$this->setData(['user', $this->getUrl(2), 'connectFail', 0], false);
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0], false);
// Sauvegarde la base manuellement
$this->saveDB('user');
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Nouveau mot de passe enregistré'),
@ -1567,7 +1602,7 @@ class user extends common
"accessCsrf" => null,
'tags' => $item['tags']
]
]);
], false);
// Icône de notification
$item['notification'] = $create ? template::ico('check') : template::ico('cancel');
// Envoi du mail
@ -1608,6 +1643,8 @@ class user extends common
}
}
// Sauvegarde la base manuellement
$this->saveDB(module: 'user');
if (empty(self::$users)) {
$notification = helper::translate('Rien à importer, erreur de format ou fichier incorrect');
$success = false;
@ -1668,7 +1705,7 @@ class user extends common
if (
isset($_POST['usersTagSubmit'])
) {
$notification = helper::translate('Modification de %s étiquette');
$notification = helper::translate('Modification de %s étiquette(s)');
$success = true;
$count = 0;
$newTags = $this->getInput('usersTagLabel', null, true);
@ -1677,10 +1714,12 @@ class user extends common
if (
$this->getData(['user', $keyPost]) !== null
) {
$this->setData(['user', $keyPost, 'tags', $newTags]);
$count += 1;
$this->setData(['user', $keyPost, 'tags', $newTags], false);
$count += 1;
}
}
// Sauvegarde la base manuellement
$this->saveDB(module: 'user');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user/tag',
@ -1689,7 +1728,7 @@ class user extends common
]);
}
// Liste des groupes et des profils
$usersGroups = $this->getData(['profil']);

View File

@ -29,6 +29,7 @@ $(document).ready((function () {
},
locale: 'fr',
stateSave: true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
"columnDefs": [
{
target: 5,

View File

@ -8,4 +8,32 @@
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready((function(){$(".zwiico-eye").mouseenter((function(){$("#userLoginPassword").attr("type","text")})),$(".zwiico-eye").mouseleave((function(){$("#userLoginPassword").attr("type","password")}))}));
$(document).ready((function() {
$("#userLoginId").on("change keydown keyup", function (event) {
var userId = $(this).val();
if (
event.keyCode !== 8 // BACKSPACE
&& event.keyCode !== 37 // LEFT
&& event.keyCode !== 39 // RIGHT
&& event.keyCode !== 46 // DELETE
&& window.getSelection().toString() !== userId // Texte sélectionné
) {
var searchReplace = {
"á": "a", "à": "a", "â": "a", "ä": "a", "ã": "a", "å": "a", "ç": "c", "é": "e", "è": "e", "ê": "e", "ë": "e", "í": "i", "ì": "i", "î": "i", "ï": "i", "ñ": "n", "ó": "o", "ò": "o", "ô": "o", "ö": "o", "õ": "o", "ú": "u", "ù": "u", "û": "u", "ü": "u", "ý": "y", "ÿ": "y",
"Á": "A", "À": "A", "Â": "A", "Ä": "A", "Ã": "A", "Å": "A", "Ç": "C", "É": "E", "È": "E", "Ê": "E", "Ë": "E", "Í": "I", "Ì": "I", "Î": "I", "Ï": "I", "Ñ": "N", "Ó": "O", "Ò": "O", "Ô": "O", "Ö": "O", "Õ": "O", "Ú": "U", "Ù": "U", "Û": "U", "Ü": "U", "Ý": "Y", "Ÿ": "Y",
"'": "-", "\"": "-", " ": "-"
};
userId = userId.replace(/[áàâäãåçéèêëíìîïñóòôöõúùûüýÿ'" ]/ig, function (match) {
return searchReplace[match];
});
userId = userId.replace(/[^a-z0-9-]/ig, "");
$(this).val(userId);
}
});
$(".zwiico-eye").mouseenter((function() {
$("#userLoginPassword").attr("type", "text")
})), $(".zwiico-eye").mouseleave((function() {
$("#userLoginPassword").attr("type", "password")
}))
}));

View File

@ -196,7 +196,7 @@
<?php echo template::checkbox('profilAddCourseUserHistory', true, 'Voir historique d\'un participant'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddCourseUserHistoryExport', true, 'Exporter historique d\'un participant'); ?>
<?php echo template::checkbox('profilAddCourseuserReportExport', true, 'Exporter historique d\'un participant'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddCourseUserDelete', true, 'Désinscrire un participant'); ?>

View File

@ -56,10 +56,10 @@ $(document).ready(function () {
if ($('#profilEditCourseUsers').is(':checked')) {
// Activer les autres checkboxes
$('#profilEditCourseUserHistory, #profilEditCourseUserHistoryExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
} else {
// Désactiver les autres checkboxes
$('#profilEditCourseUserHistory, #profilEditCourseUserHistoryExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('checked', false).prop('disabled', true);
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('checked', false).prop('disabled', true);
// Désactiver les modules et tout décocher
$(".courseContainer").slideUp();
$('.courseContainer input[type="checkbox"]').prop('checked', false);
@ -135,11 +135,11 @@ $(document).ready(function () {
$('#profilEditCourseUsers').change(function () {
if ($(this).is(':checked')) {
// Activer les autres checkboxes
$('#profilEditCourseUserHistory, #profilEditCourseUserHistoryExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
} else {
// Désactiver les autres checkboxes
$('#profilEditCourseUserHistory, #profilEditCourseUserHistoryExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('checked', false).prop('disabled', true);
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('checked', false).prop('disabled', true);
// Désactiver les modules et tout décocher
$(".courseContainer").slideUp();
$('.courseContainer input[type="checkbox"]').prop('checked', false);

View File

@ -291,8 +291,8 @@
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilEditCourseUserHistoryExport', true, 'Exporter historique d\'un participant', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'userHistoryExport']),
<?php echo template::checkbox('profilEditCourseuserReportExport', true, 'Exporter historique d\'un participant', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'userReportExport']),
]); ?>
</div>
<div class="col3">

View File

@ -7,7 +7,7 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<div class="col1 offset10">
<?php echo template::submit('usersDeleteSubmit', [
'class' => 'buttonRed',
'ico' => '',

View File

@ -1,5 +1,7 @@
[
"datatables.min.js",
"datatables.min.js",
"moment.min.js",
"datetime.min.js",
"datatables.min.css",
"datatables.custom.css"
]

View File

@ -1506,8 +1506,9 @@ class UploadHandler
}
$thumbResult = create_img($targetFile, $targetFileThumb, 122, 91);
$newWidth = 640;
$newHeight = 480;
$thumbResult = create_img($targetFile, $targetFileThumb, $newWidth, $newHeight);
if ( $thumbResult!==true)
{

View File

@ -19,7 +19,7 @@ setlocale(LC_CTYPE, $lang);
/* Lecture du groupe de l'utilisateur connecté pour attribuer les droits et les dossiers */
$userId = $_COOKIE['ZWII_USER_ID'];
$courseId = $_COOKIE['ZWII_SITE_CONTENT'];
$courseId = $_GET['lang'];
$u = json_decode(file_get_contents('../../../site/data/user.json'), true);
$g = json_decode(file_get_contents('../../../site/data/profil.json'), true);
@ -609,7 +609,7 @@ $config = array(
// path_from_filemanager/test/test1/
// PS if there isn't write permission in your destination folder you must set it
//
'fixed_image_creation' => true,
'fixed_image_creation' => false,
//activate or not the creation of one or more image resized with fixed path from filemanager folder
'fixed_path_from_filemanager' => array('../../../site/file/thumb/'),
//fixed path of the image folder from the current position on upload folder

View File

@ -10,23 +10,43 @@
if (typeof (privateKey) == 'undefined') {
var privateKey = null;
};
tinymce.init({
// Classe où appliquer l'éditeur
selector: ".editorWysiwyg",
// Aperçu dans le pied de page
setup: function (ed) {
ed.on('change', function (e) {
if (ed.id === 'themeFooterText') {
setup: function (editor) {
// Événement 'change'
editor.on('change', function (e) {
if (editor.id === 'themeFooterText') {
$("#footerText").html(tinyMCE.get('themeFooterText').getContent());
}
if (ed.id === 'themeHeaderText') {
if (editor.id === 'themeHeaderText') {
$("#featureContent").html(tinyMCE.get('themeHeaderText').getContent());
}
});
// Événement 'init'
// Cette partie permet de récupérer l'attribut de zwii_site_content qui contient le code de l'espace ouvert stocké dans la session php
editor.on('init', function () {
var siteContent = document.getElementById('zwii_site_content').getAttribute('data-variable');
siteContent = siteContent === null ? 'home' : siteContent;
// Charger le contenu CSS avec siteContent
var newStylesheetUrls = [
baseUrl + "core/layout/common.css",
baseUrl + "core/vendor/tinymce/content.css",
baseUrl + "site/data/" + siteContent + "/theme.css",
baseUrl + "site/data/custom.css"
];
// Supprime les anciennes feuilles de style si nécessaire
newStylesheetUrls.forEach(function(url) {
editor.dom.loadCSS(url); // Charger les nouvelles feuilles de style
});
});
},
// Langue
language: getCookie('ZWII_UI') === null ? "fr_FR" : getCookie('ZWII_UI'),
language:"fr_FR",
// Plugins
plugins: "advlist anchor autolink autoresize autosave codemirror contextmenu colorpicker fullscreen hr image imagetools link lists media paste searchreplace tabfocus table template textcolor visualblocks nonbreaking emoticons charmap textpattern",
// Contenu du menu
@ -35,7 +55,6 @@ tinymce.init({
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
view: { title: 'View', items: 'code | visualaid visualblocks | fullscreen' },
insert: { title: 'Insert', items: 'image link media pageembed template inserttable | charmap emoticons hr | nonbreaking anchor' },
//format: { title: 'Format', items: 'bold italic underline strikethrough superscript subscript codeformat | styles blocks fontfamily fontsize align lineheight | forecolor backcolor | removeformat' },
tools: { title: 'Tools', items: '' },
table: { title: 'Table', items: 'inserttable | cell row column | tableprops deletetable' },
help: { title: 'Help', items: 'help' }
@ -56,7 +75,6 @@ tinymce.init({
saveCursorPosition: false, // Insert caret marker
config: { // CodeMirror config object
fullscreen: true,
/*mode: 'application/x-httpd-php',*/
lineNumbers: true,
indentUnit: 4,
mode: "htmlmixed"
@ -71,12 +89,8 @@ tinymce.init({
'addon/search/searchcursor.js',
'addon/search/search.js',
],
/*
cssFiles: [
'theme/cobalt.css',
],*/
width: 800, // Default value is 800
height: 500 // Default value is 550
width: 800,
height: 500
},
// Cibles de la target
target_list: [
@ -89,7 +103,7 @@ tinymce.init({
{ title: 'Une popup (Lity)', value: 'data-lity' },
{ title: 'Une galerie d\'images (SimpleLightbox)', value: 'gallery' }
],
// Titre des image
// Titre des images
image_title: true,
// Pages internes
link_list: baseUrl + "core/vendor/tinymce/links.php",
@ -99,7 +113,7 @@ tinymce.init({
content_css: [
baseUrl + "core/layout/common.css",
baseUrl + "core/vendor/tinymce/content.css",
baseUrl + "site/data/"+ (getCookie("ZWII_SITE_CONTENT") === null ? 'home' : getCookie("ZWII_SITE_CONTENT")) +"/theme.css",
baseUrl + "site/data/home/theme.css", // Ceci sera mis à jour dans l'événement 'init'
baseUrl + "site/data/custom.css"
],
// Classe à ajouter à la balise body dans l'iframe
@ -226,26 +240,26 @@ tinymce.init({
}
],
textpattern_patterns: [
{start: '*', end: '*', format: 'italic'},
{start: '**', end: '**', format: 'bold'},
{start: '#', format: 'h1'},
{start: '##', format: 'h2'},
{start: '###', format: 'h3'},
{start: '####', format: 'h4'},
{start: '#####', format: 'h5'},
{start: '######', format: 'h6'},
{start: '1. ', cmd: 'InsertOrderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'},
{start: '1. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' }},
{start: '1) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' }},
{start: 'a. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' }},
{start: 'a) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' }},
{start: 'i. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' }},
{start: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' }}
]
{ start: '*', end: '*', format: 'italic' },
{ start: '**', end: '**', format: 'bold' },
{ start: '#', format: 'h1' },
{ start: '##', format: 'h2' },
{ start: '###', format: 'h3' },
{ start: '####', format: 'h4' },
{ start: '#####', format: 'h5' },
{ start: '######', format: 'h6' },
{ start: '1. ', cmd: 'InsertOrderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' },
{ start: '1. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' } },
{ start: '1) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' } },
{ start: 'a. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' } },
{ start: 'a) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' } },
{ start: 'i. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' } },
{ start: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' } }
]
});
@ -302,7 +316,7 @@ tinymce.init({
});
},
// Langue
language: getCookie('ZWII_UI') === null ? "fr_FR" : getCookie('ZWII_UI'),
language: "fr_FR",
// Plugins
plugins: "advlist anchor autolink autoresize autosave colorpicker contextmenu hr lists paste searchreplace tabfocus template textcolor textpattern",
// Contenu de la barre d'outils
@ -344,26 +358,26 @@ tinymce.init({
document_base_url: baseUrl,
max_height: 200,
textpattern_patterns: [
{start: '*', end: '*', format: 'italic'},
{start: '**', end: '**', format: 'bold'},
{start: '#', format: 'h1'},
{start: '##', format: 'h2'},
{start: '###', format: 'h3'},
{start: '####', format: 'h4'},
{start: '#####', format: 'h5'},
{start: '######', format: 'h6'},
{start: '1. ', cmd: 'InsertOrderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'},
{start: '1. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' }},
{start: '1) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' }},
{start: 'a. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' }},
{start: 'a) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' }},
{start: 'i. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' }},
{start: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' }}
]
{ start: '*', end: '*', format: 'italic' },
{ start: '**', end: '**', format: 'bold' },
{ start: '#', format: 'h1' },
{ start: '##', format: 'h2' },
{ start: '###', format: 'h3' },
{ start: '####', format: 'h4' },
{ start: '#####', format: 'h5' },
{ start: '######', format: 'h6' },
{ start: '1. ', cmd: 'InsertOrderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' },
{ start: '1. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' } },
{ start: '1) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'decimal' } },
{ start: 'a. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' } },
{ start: 'a) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-alpha' } },
{ start: 'i. ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' } },
{ start: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' } }
]
});

View File

@ -14,11 +14,35 @@
* @link http://zwiicms.fr/
*/
/**
/**
* Initialisation de Zwii
*/
// Remplace la directive htaccess
ini_set('session.use_trans_sid', FALSE);
// Crée un identifiant unique pour chaque site en fonction du nom de domaine ou autre
$siteId = md5($_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_FILENAME']); // Ou utilise un autre identifiant unique pour chaque site
// Change le nom de la session en fonction de cet identifiant
session_name('zwii_session_' . $siteId);
// Récupère dynamiquement le chemin du dossier dans lequel le script est exécuté
$scriptPath = dirname($_SERVER['SCRIPT_NAME']);
// Si le chemin est vide (ce qui peut arriver si le site est à la racine), définis-le comme '/'
if ($scriptPath === '/' || $scriptPath === '\\' || $scriptPath === '.') {
$scriptPath = '/';
}
// Définissez le chemin du cookie de session dynamiquement
session_set_cookie_params([
'lifetime' => 0,
'path' => $scriptPath, // Utilise le chemin du script pour restreindre la session à ce répertoire
'domain' => $_SERVER['SERVER_NAME'], // Domaine par défaut
'secure' => isset($_SERVER['HTTPS']), // Pour HTTPS, si nécessaire
'httponly' => true,
'samesite' => 'Lax' // Ou 'Strict' ou 'None' selon tes besoins
]);
// Démarre la session
session_start();
@ -34,7 +58,7 @@ include_once('core/include/checkup.php');
* fr_FR.utf8 : la majorité
*/
date_default_timezone_set('Europe/Paris');
setlocale (LC_ALL, 'fr_FR.UTF8', 'fr_FR', 'french');
setlocale(LC_ALL, 'fr_FR.UTF8', 'fr_FR', 'french');
/**
* Chargement des classes
@ -47,4 +71,4 @@ spl_autoload_register('core::autoload');
* Chargement du coeur
*/
$core = new core;
echo $core->router();
echo $core->router();

View File

@ -16,7 +16,7 @@
class blog extends common
{
const VERSION = '7.11';
const VERSION = '8.0';
const REALNAME = 'Blog';
const DELETE = true;
const UPDATE = '0.0';
@ -174,10 +174,12 @@ class blog extends common
$this->setData(['module', $this->getUrl(0), 'config', 'timeFormat', '%H:%M']);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.5']);
}
// Version 7.4
if (version_compare($this->getData(['module', $this->getUrl(0), 'config', 'versionData']), '7.4', '<')) {
// Version 8.0
if (version_compare($this->getData(['module', $this->getUrl(0), 'config', 'versionData']), '8.0', '<')) {
$this->setData(['module', $this->getUrl(0), 'config', 'buttonBack', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '7.4']);
$this->setData(['module', $this->getUrl(0), 'config', 'showTime', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showDate', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '8.0']);
}
}
@ -578,7 +580,9 @@ class blog extends common
'itemsperPage' => $this->getInput('blogOptionItemsperPage', helper::FILTER_INT, true),
'dateFormat' => $this->getInput('blogOptionDateFormat'),
'timeFormat' => $this->getInput('blogOptionTimeFormat'),
'buttonBack' => $this->getInput('newsOptionButtonBack'),
'buttonBack' => $this->getInput('blogOptionButtonBack', helper::FILTER_BOOLEAN),
'showDate' => $this->getInput('blogOptionShowDate', helper::FILTER_BOOLEAN),
'showTime' => $this->getInput('blogOptionShowTime', helper::FILTER_BOOLEAN),
'versionData' => $this->getData(['module', $this->getUrl(0), 'config', 'versionData']),
]
]);
@ -596,7 +600,6 @@ class blog extends common
]);
}
/**
* Suppression
*/
@ -749,7 +752,7 @@ class blog extends common
) {
// Check la captcha
if (
$this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === false
//AND $this->getInput('blogArticlecaptcha', helper::FILTER_INT) !== $this->getInput('blogArticlecaptchaFirstNumber', helper::FILTER_INT) + $this->getInput('blogArticlecaptchaSecondNumber', helper::FILTER_INT))
and password_verify($this->getInput('blogArticleCaptcha', helper::FILTER_INT), $this->getInput('blogArticleCaptchaResult')) === false
) {
@ -831,7 +834,7 @@ class blog extends common
// Signature de l'article
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
// Signature du commentaire édité
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
if ($this->isConnected() === true) {
self::$editCommentSignature = $this->signature($this->getUser('id'));
}
// Commentaires en fonction de la pagination

View File

@ -1,6 +1,11 @@
# Versions 7.11
# Version 8.00
- Ajoute deux nouvelles options pour afficher ou masquer la date et l'heure de l'article.
- Corrige un bug d'affichage des articles lorsque le thème Moderne est sélectionné.
- Corrige un bug dans la méthode de tronquage de l'article, nécessite Zwii 13.5
- Corrige un mauvais format de la propriété buttonBack non stockée au type booléen.
# Version 7.11
- Le sélecteur de fichier affiche par défaut le chemin vers le fichier présent dans le champ.
# Versions 7.10
# Version 7.10
- Empêche la validation d'un commentaire lorsque le contenu est vide.
# Versions 7.8 - 7.9
- Le flux RSS ne fonctionne pas si les méta de la page sont vides.

View File

@ -1 +1 @@
{"name":"blog","realName":"Blog","version":"7.10","update":"0.0","delete":true,"dataDirectory":""}
{"name":"blog","realName":"Blog","version":"7.12","update":"0.0","delete":true,"dataDirectory":""}

View File

@ -18,14 +18,31 @@
<?php endif; ?>
</div>
<div class="col6 newsDate textAlignRight">
<!-- bloc signature et date -->
<!-- bloc signature -->
<?php echo template::ico('user'); ?>
<?php echo $module::$articleSignature; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI) . ' ' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<!-- bloc date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'editConsent']) === $module::EDIT_OWNER
@ -88,7 +105,7 @@
'readonly' => true
]); ?>
<div id="blogArticleCommentWrapper" class="displayNone">
<?php if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')): ?>
<?php if ($this->isConnected() === true): ?>
<?php echo template::text('blogArticleUserName', [
'label' => 'Nom',
'readonly' => true,
@ -122,7 +139,7 @@
'maxlength' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'commentMaxlength'])
]); ?>
<div id="blogArticleContentAlarm"> </div>
<?php if ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')): ?>
<?php if ($this->isConnected() === false): ?>
<div class="row">
<div class="col12">
<?php echo template::captcha('blogArticleCaptcha', [

View File

@ -24,11 +24,28 @@
</div>
<div class="row">
<div class="col6 blogEdit">
<!-- bloc signature et date -->
<!-- bloc signature -->
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<!-- bloc Date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
</div>
</div>
<div class="row">
@ -51,7 +68,7 @@
<div class="col6 blogEdit">
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'editConsent']) === $module::EDIT_OWNER
@ -103,18 +120,19 @@
file_exists(self::FILE_DIR . 'source/' . $article['picture'])
): ?>
<div class="col3">
<?php // Déterminer le nom de la miniature
$parts = pathinfo($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'picture']));
$thumb = 'mini_' . $parts['basename'];
// Créer la miniature si manquante
if (!file_exists(self::FILE_DIR . 'thumb/' . $thumb)) {
$this->makeThumb(
self::FILE_DIR . 'source/' . $article['picture'],
self::FILE_DIR . 'thumb/' . $thumb,
self::THUMBS_WIDTH
);
}
?>
<?php
// Déterminer le nom de la miniature
$parts = pathinfo($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'picture']));
$thumb = 'mini_' . $parts['basename'];
// Créer la miniature si manquante
if (!file_exists(self::FILE_DIR . 'thumb/' . $thumb)) {
$this->makeThumb(
self::FILE_DIR . 'source/' . $article['picture'],
self::FILE_DIR . 'thumb/' . $thumb,
self::THUMBS_WIDTH
);
}
?>
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>" class="blogPicture">
<img src="<?php echo helper::baseUrl(false) . self::FILE_DIR . 'thumb/' . $thumb; ?>"
alt="<?php echo $article['picture']; ?>">
@ -138,21 +156,43 @@
</a>
</div>
<div class="blogDate">
<!-- bloc signature et date -->
<!-- bloc signature -->
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
</div>
<div class="blogContent">
<?php $lenght = $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']) !== 0 ? $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']) : 500 ?>
<?php echo helper::subword(strip_tags($article['content'], '<br><p>'), 0, $lenght); ?>...
<div class="readMoreContainer">
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>">
<button class="readMoreButton">
<?php echo helper::translate('Lire la suite'); ?>
</button>
</a>
<!-- bloc date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<div class="blogContent">
<?php $lenght = $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']); ?>
<?php if ($lenght > 0): ?>
<?php ?>
<?php echo helper::subword($article['content'], 0, $lenght); ?>...
<div class="readMoreContainer">
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>">
<button class="readMoreButton">
<?php echo helper::translate('Lire la suite'); ?>
</button>
</a>
</div>
<?php else: ?>
<?php echo $article['content']; ?>
<?php endif; ?>
</div>
</div>
</div>

View File

@ -0,0 +1,40 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready(function() {
// Gestion du changement de la case "Afficher la date"
$('#blogOptionShowDate').change(function() {
var showDateChecked = $(this).is(':checked');
// Afficher ou masquer le wrapper de l'heure selon l'état de la date
if (showDateChecked) {
$('.timeWrapper').show();
} else {
$('.timeWrapper').hide();
// Désactiver l'option "Afficher l'heure" lorsque la date est désactivée
$('#blogOptionShowTime').prop('checked', false).trigger('change');
}
// Afficher ou masquer le format de la date
$('#blogOptionDateFormatWrapper').toggle(showDateChecked);
}).trigger('change'); // Déclenchement au chargement de la page
// Gestion du changement de la case "Afficher l'heure"
$('#blogOptionShowTime').change(function() {
var showTimeChecked = $(this).is(':checked');
// Afficher ou masquer le format de l'heure
$('#blogOptionTimeFormatWrapper').toggle(showTimeChecked);
}).trigger('change'); // Déclenchement au chargement de la page
});

View File

@ -19,30 +19,22 @@
</h4>
<div class="row">
<div class="col3">
<?php echo template::select('blogOptionArticlesLayout', $module::$articlesLayout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
<?php echo template::checkbox('blogOptionShowDate', true, 'Afficher la date', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showDate']),
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogOptionArticlesLenght', $module::$articlesLenght, [
'label' => 'Aperçus',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('blogOptionItemsperPage', $module::$ArticlesListed, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('blogOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col2">
<div class="col3 timeWrapper">
<?php echo template::checkbox('blogOptionShowTime', true, 'Afficher l\'heure', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showTime']),
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::select('blogOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
@ -50,19 +42,39 @@
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('blogOptionArticlesLayout', $module::$articlesLayout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogOptionArticlesLenght', $module::$articlesLenght, [
'label' => 'Aperçus',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogOptionItemsperPage', $module::$ArticlesListed, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('blogOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('blogOptionFeedslabel', [
'label' => 'Texte de l\'étiquette',
'label' => 'Texte de l\'étiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>

View File

@ -27,8 +27,6 @@ $( document ).ready(function() {
serializeRegexp: ""
});
console.log($("#galleryEditSort").val());
if ($("#galleryEditSort").val() !== "SORT_HAND") {
$("#galleryTable tr").addClass("nodrag nodrop");
$(".zwiico-sort").hide();

View File

@ -1,3 +1,6 @@
# Versions 6.0
- Ajoute deux nouvelles options pour afficher ou masquer la date et l'heure de l'article.
- Corrige un mauvais format de la propriété buttonBack non stockée au type booléen.
# Versions 5.9
- Largeur d'un bouton de retour.
# Versions 5.7 - 5.8

View File

@ -16,7 +16,7 @@
class news extends common
{
const VERSION = '5.9';
const VERSION = '6.0';
const REALNAME = 'News';
const DATADIRECTORY = self::DATA_DIR . 'news/';
@ -124,11 +124,12 @@ class news extends common
$feeds = new \FeedWriter\RSS2();
// En-tête
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']) ? $this->getData(['page', $this->getUrl(0), 'title']): '');
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']) ? $this->getData(['page', $this->getUrl(0), 'title']) : '');
$feeds->setLink(helper::baseUrl() . $this->getUrl(0));
if ($this->getData(['page', $this->getUrl(0), 'metaDescription'])) {
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
};
}
;
$feeds->setChannelElement('language', 'fr-FR');
$feeds->setDate(date('r', time()));
$feeds->addGenerator();
@ -174,7 +175,8 @@ class news extends common
$publishedOn = $this->getInput('newsAddPublishedOn', helper::FILTER_DATETIME, true);
$publishedOff = $this->getInput('newsAddPublishedOff') ? $this->getInput('newsAddPublishedOff', helper::FILTER_DATETIME) : '';
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'posts',
$newsId,
[
@ -288,7 +290,8 @@ class news extends common
// Fin feuille de style
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'theme',
[
'style' => $success ? self::DATADIRECTORY . $this->getUrl(0) . '/theme.css' : '',
@ -300,7 +303,8 @@ class news extends common
]);
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'config',
[
'feeds' => $this->getInput('newsOptionShowFeeds', helper::FILTER_BOOLEAN),
@ -310,7 +314,9 @@ class news extends common
'height' => $this->getInput('newsOptionHeight', helper::FILTER_INT, true),
'dateFormat' => $this->getInput('newsOptionDateFormat'),
'timeFormat' => $this->getInput('newsOptionTimeFormat'),
'buttonBack' => $this->getInput('newsOptionButtonBack'),
'buttonBack' => $this->getInput('newsOptionButtonBack', helper::FILTER_BOOLEAN),
'showDate' => $this->getInput('newsOptionShowDate', helper::FILTER_BOOLEAN),
'showTime' => $this->getInput('newsOptionShowTime', helper::FILTER_BOOLEAN),
'versionData' => $this->getData(['module', $this->getUrl(0), 'config', 'versionData']),
]
]);
@ -318,7 +324,7 @@ class news extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/option',
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => helper::translate('Modifications enregistrées'),
'state' => true
]);
@ -428,7 +434,8 @@ class news extends common
$publishedOn = $this->getInput('newsEditPublishedOn', helper::FILTER_DATETIME, true);
$publishedOff = $this->getInput('newsEditPublishedOff') ? $this->getInput('newsEditPublishedOff', helper::FILTER_DATETIME) : '';
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'posts',
$newsId,
[
@ -490,6 +497,8 @@ class news extends common
}
// L'article existe
else {
self::$dateFormat = $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat']);
self::$timeFormat = $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat']);
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
// Valeurs en sortie
$this->addOutput([
@ -609,6 +618,14 @@ class news extends common
// Mettre à jour la version
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '5.3']);
}
// Mise à jour 6.0
if (version_compare($versionData, '6.0', '<')) {
$this->setData(['module', $this->getUrl(0), 'config', 'buttonBack', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showTime', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showDate', true]);
// Mettre à jour la version
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.0']);
}
}

View File

@ -12,28 +12,42 @@
<?php endif; ?>
</div>
<div class="col6 newsDate textAlignRight">
<!-- bloc signature et date -->
<!-- bloc signature -->
<?php echo template::ico('user'); ?>
<?php echo $module::$articleSignature . ' - '; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8('%d %B %Y', $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI) . '&nbsp' . helper::dateUTF8('%H:%M', $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<!-- Bloc edition -->
<?php echo $module::$articleSignature; ?>
<!-- bloc date -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?> <!-- Bloc edition -->
<?php if (
$this->isConnected() === true
and
( // Propriétaire
($this->getUser('group') === self::GROUP_ADMIN)
)
): ?>
&nbsp;-&nbsp;
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $this->getUrl(1); ?>">
<?php echo template::ico('pencil'); ?>
<?php echo template::ico('pencil', ['margin' => 'left']); ?>
<?php echo helper::translate('Éditer'); ?>
</a>
<?php endif; ?>
<!-- Bloc RSS-->
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'feeds'])): ?>
&nbsp;-&nbsp;
<div id="rssFeed">
<a type="application/rss+xml" href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>"
target="_blank">

View File

@ -1,5 +1,6 @@
<?php if ($module::$news): ?>
<link rel="stylesheet" type="text/css" href="<?php echo helper::baseUrl(false) . $this->getData(['module', $this->getUrl(0), 'theme', 'style']);?> "/>
<link rel="stylesheet" type="text/css"
href="<?php echo helper::baseUrl(false) . $this->getData(['module', $this->getUrl(0), 'theme', 'style']); ?> " />
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'feeds'])): ?>
<div id="rssFeed">
<a type="application/rss+xml" href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" target="_blank">
@ -20,22 +21,38 @@
<?php echo '<a href="' . helper::baseUrl(true) . $this->getUrl(0) . '/' . $newsId . '">' . $news['title'] . '</a>'; ?>
</h2>
<div class="newsSignature">
<!-- bloc signature -->
<?php echo template::ico('user'); ?>
<?php echo $news['userId'] . ' - '; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $news['publishedOn'], self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $news['publishedOn'], self::$i18nUI); ?>
<?php echo $news['userId']; ?>
<!-- bloc Date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getUser('group') === self::GROUP_ADMIN)
)
): ?>
&nbsp;-&nbsp;
<a
href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $newsId; ?>">
<?php echo template::ico('pencil'); ?> Éditer
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $newsId; ?>">
<?php echo template::ico('pencil', ['margin' => 'left']); ?> Éditer
</a>
<?php endif; ?>
</div>
@ -51,7 +68,6 @@
</div>
</div>
<?php endforeach; ?>
</div>
</article>
<?php echo $module::$pages; ?>

View File

@ -0,0 +1,40 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready(function() {
// Gestion du changement de la case "Afficher la date"
$('#newsOptionShowDate').change(function() {
var showDateChecked = $(this).is(':checked');
// Afficher ou masquer le wrapper de l'heure selon l'état de la date
if (showDateChecked) {
$('.timeWrapper').show();
} else {
$('.timeWrapper').hide();
// Désactiver l'option "Afficher l'heure" lorsque la date est désactivée
$('#newsOptionShowTime').prop('checked', false).trigger('change');
}
// Afficher ou masquer le format de la date
$('#newsOptionDateFormatWrapper').toggle(showDateChecked);
}).trigger('change'); // Déclenchement au chargement de la page
// Gestion du changement de la case "Afficher l'heure"
$('#newsOptionShowTime').change(function() {
var showTimeChecked = $(this).is(':checked');
// Afficher ou masquer le format de l'heure
$('#newsOptionTimeFormatWrapper').toggle(showTimeChecked);
}).trigger('change'); // Déclenchement au chargement de la page
});

View File

@ -1,111 +1,123 @@
<?php echo template::formOpen('newsOption'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('newsOptionBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('newsOptionSubmit'); ?>
</div>
<div class="col1">
<?php echo template::button('newsOptionBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?></h4>
<div class="row">
<div class="col2">
<?php echo template::select('newsOptionItemsperCol', $module::$columns, [
'label' => 'Nombre de colonnes',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'itemsperCol'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('newsOptionItemsperPage', $module::$itemsList, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'itemsperPage'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('newsOptionHeight', $module::$height, [
'label' => 'Abrégé de l\'article',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'height'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('newsOptionSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?></h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionShowDate', true, 'Afficher la date', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showDate']),
]); ?>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
'help' => 'Flux limité aux articles de la première page.'
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('newsOptionFeedslabel', [
'label' => 'Étiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::checkbox('newsOptionShowTime', true, 'Afficher l\'heure', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showTime']),
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::select('newsOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('newsOptionItemsperCol', $module::$columns, [
'label' => 'Nombre de colonnes',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperCol'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('newsOptionItemsperPage', $module::$itemsList, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('newsOptionHeight', $module::$height, [
'label' => 'Abrégé de l\'article',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'height'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('newsOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
'help' => 'Flux limité aux articles de la première page.'
]); ?>
</div>
<div class="col6">
<?php echo template::text('newsOptionFeedslabel', [
'label' => 'Texte de l\'étiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Thème');?></h4>
<div class="row">
<div class="col3">
<?php echo template::select('newsThemeBorderStyle', $module::$borderStyle, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0),'theme', 'borderStyle'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsThemeBorderWidth', $module::$borderWidth, [
'label' => 'Épaisseur',
'selected' => $this->getData(['module', $this->getUrl(0),'theme', 'borderWidth'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBorderColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0),'theme', 'borderColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur du fond',
'value' => $this->getData(['module', $this->getUrl(0),'theme', 'backgroundColor'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Thème'); ?></h4>
<div class="row">
<div class="col3">
<?php echo template::select('newsThemeBorderStyle', $module::$borderStyle, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderStyle'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsThemeBorderWidth', $module::$borderWidth, [
'label' => 'Épaisseur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderWidth'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBorderColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur du fond',
'value' => $this->getData(['module', $this->getUrl(0), 'theme', 'backgroundColor'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="moduleVersion">Version
<?php echo $module::VERSION; ?>

View File

@ -58,7 +58,7 @@ class redirection extends common
{
// Message si l'utilisateur peut éditer la page
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
&& $this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUrl(1) !== 'force'
) {

View File

@ -1,3 +1,5 @@
# Version 3.3
- Une seule lecture du fichier module.json
# Version 3.2
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 3.1

View File

@ -20,7 +20,7 @@
class search extends common
{
const VERSION = '3.2';
const VERSION = '3.3';
const REALNAME = 'Recherche';
const DATADIRECTORY = self::DATA_DIR . 'search/';
@ -172,40 +172,43 @@ class search extends common
public function index()
{
// Initialise un module non configuré
$this->init();
if (
$this->isPost()
) {
if ($this->isPost()) {
//Initialisations variables
$success = true;
$result = [];
$notification = '';
$total = '';
// Récupération du mot clef passé par le formulaire de ...view/index.php, avec caractères accentués
self::$motclef = $this->getInput('searchMotphraseclef');
// Variable de travail, on conserve la variable globale pour l'affichage du résultat
$motclef = self::$motclef;
// Suppression des mots < 3 caractères et des articles > 2 caractères de la chaîne $motclef
// Suppression des mots < 3 caractères et des articles > 2 caractères de la chaîne $motclef
$arraymotclef = explode(' ', $motclef);
$motclef = '';
foreach ($arraymotclef as $key => $value) {
if (strlen($value) > 2 && $value !== 'les' && $value !== 'des' && $value !== 'une' && $value !== 'aux')
if (strlen($value) > 2 && $value !== 'les' && $value !== 'des' && $value !== 'une' && $value !== 'aux') {
$motclef .= $value . ' ';
}
}
// Suppression du dernier ' '
if ($motclef !== '')
if ($motclef !== '') {
$motclef = substr($motclef, 0, strlen($motclef) - 1);
}
// Récupération de l'état de l'option mot entier passé par le même formulaire
self::$motentier = $this->getInput('searchMotentier', helper::FILTER_BOOLEAN);
// Lecture unique des données du module
$moduleData = $this->getData(['module']);
if ($motclef !== '') {
foreach ($this->getHierarchy(null, false, null) as $parentId => $childIds) {
// Vérification des conditions pour la page parente
if (
$this->getData(['page', $parentId, 'disable']) === false &&
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
@ -213,7 +216,6 @@ class search extends common
) {
$url = $parentId;
$titre = $this->getData(['page', $parentId, 'title']);
//$content = file_get_contents(self::DATA_DIR . self::$siteContent . '/content/' . $this->getData(['page', $parentId, 'content']));
$content = $this->getPage($parentId, self::$siteContent);
$content = $titre . ' ' . $content;
// Pages sauf pages filles et articles de blog
@ -222,9 +224,9 @@ class search extends common
$result[] = $tempData;
}
}
// Vérification des sous-pages et articles de sous-pages
foreach ($childIds as $childId) {
// Sous page
if (
$this->getData(['page', $childId, 'disable']) === false &&
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
@ -232,24 +234,21 @@ class search extends common
) {
$url = $childId;
$titre = $this->getData(['page', $childId, 'title']);
//$content = file_get_contents(self::DATA_DIR . self::$siteContent . '/content/' . $this->getData(['page', $childId, 'content']));
$content = $this->getPage($childId, self::$siteContent);
$content = $titre . ' ' . $content;
//Pages filles
$tempData = $this->occurrence($url, $titre, $content, $motclef, self::$motentier);
if (is_array($tempData)) {
$result[] = $tempData;
}
}
// Articles d'une sous-page blog ou de news
if ($this->getData(['module', $childId, 'posts'])) {
foreach ($this->getData(['module', $childId, 'posts']) as $articleId => $article) {
if ($this->getData(['module', $childId, 'posts', $articleId, 'state']) === true) {
if (isset($moduleData[$childId]['posts'])) {
foreach ($moduleData[$childId]['posts'] as $articleId => $article) {
if ($article['state'] === true) {
$url = $childId . '/' . $articleId;
$titre = $article['title'];
$contenu = ' ' . $titre . ' ' . $article['content'];
// Articles de sous-page de type blog
$tempData = $this->occurrence($url, $titre, $contenu, $motclef, self::$motentier);
if (is_array($tempData)) {
$result[] = $tempData;
@ -258,12 +257,11 @@ class search extends common
}
}
}
// Articles d'un blog ou de news
if ($this->getData(['module', $parentId, 'posts'])) {
foreach ($this->getData(['module', $parentId, 'posts']) as $articleId => $article) {
if ($this->getData(['module', $parentId, 'posts', $articleId, 'state']) === true) {
if (isset($moduleData[$parentId]['posts'])) {
foreach ($moduleData[$parentId]['posts'] as $articleId => $article) {
if ($article['state'] === true) {
$url = $parentId . '/' . $articleId;
$titre = $article['title'];
$contenu = ' ' . $titre . ' ' . $article['content'];
@ -275,22 +273,21 @@ class search extends common
}
}
}
// Message de synthèse de la recherche
if (count($result) === 0) {
self::$resultTitle = helper::translate('Aucun résultat');
self::$resultError = helper::translate('Avez-vous pensé aux accents ?');
} else {
self::$resultError = '';
//self::$resultTitle = sprintf(' %s',helper::translate('Résultat de votre recherche'));
rsort($result);
foreach ($result as $key => $value) {
$r[] = $value['preview'];
}
// Générer une chaine de caractères
self::$resultList = implode("", $r);
}
}
// Valeurs en sortie, affichage du résultat
$this->addOutput([
'view' => 'index',
@ -309,6 +306,8 @@ class search extends common
]);
}
}
// Fonction de recherche des occurrences dans $contenu

View File

@ -0,0 +1,9 @@
# Version 2.3
- Warning lors de la saisie d'un email vide
# Version 2.2
- Ajoute la gestion des profils
# Version 2.1
- N'envoie pas d'email lorsque le domaine est invalide.
- Corrige la validation de domaines multiples séparés par des points virgules.
# Version 2.0
- trop de corrections.

View File

@ -1 +1 @@
{"name":"suscribe","realName":"Auto inscription","version":"2.00","update":"0.0","delete":true,"dataDirectory":""}
{"name":"suscribe","realName":"Auto Inscription","version":"2.3","update":"0.0","delete":true,"dataDirectory":""}

View File

@ -1,9 +1,9 @@
<?php $moduleData['suscribe'] = [
'edit' => $this->getInput('profilAddSuscribeEdit', helper::FILTER_BOOLEAN),
'delete' => $this->getInput('profilAddSuscribeDelete', helper::FILTER_BOOLEAN),
'user' => $this->getInput('profilAddSuscribeUser', helper::FILTER_BOOLEAN),
'config' => $this->getInput('profilAddSuscribeAdd', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeEdit', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeDelete', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeUser', helper::FILTER_BOOLEAN)
<?php $moduleData['suscribe'] = [
'edit' => $this->getInput('profilAddSuscribeEdit', helper::FILTER_BOOLEAN),
'delete' => $this->getInput('profilAddSuscribeDelete', helper::FILTER_BOOLEAN),
'user' => $this->getInput('profilAddSuscribeUser', helper::FILTER_BOOLEAN),
'config' => $this->getInput('profilAddSuscribeAdd', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeEdit', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeDelete', helper::FILTER_BOOLEAN) ||
$this->getInput('profilAddSuscribeUser', helper::FILTER_BOOLEAN)
];

View File

@ -1,9 +1,9 @@
<?php $moduleData['suscribe'] = [
'edit' => $this->getInput('profilEditSuscribeEdit', helper::FILTER_BOOLEAN),
'delete' => $this->getInput('profilEditSuscribeDelete', helper::FILTER_BOOLEAN),
'user' => $this->getInput('profilEditSuscribeUser', helper::FILTER_BOOLEAN),
'config' => $this->getInput('profilEditSuscribeAdd', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeEdit', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeDelete', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeUser', helper::FILTER_BOOLEAN)
<?php $moduleData['suscribe'] = [
'edit' => $this->getInput('profilEditSuscribeEdit', helper::FILTER_BOOLEAN),
'delete' => $this->getInput('profilEditSuscribeDelete', helper::FILTER_BOOLEAN),
'user' => $this->getInput('profilEditSuscribeUser', helper::FILTER_BOOLEAN),
'config' => $this->getInput('profilEditSuscribeAdd', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeEdit', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeDelete', helper::FILTER_BOOLEAN) ||
$this->getInput('profilEditSuscribeUser', helper::FILTER_BOOLEAN)
];

View File

@ -1,20 +1,20 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo sprintf('%s %s', helper::translate('Permissions'), helper::translate('Auto-inscription')); ?>
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeEdit', true, 'Éditer inscription'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeDelete', true, 'Effacer inscription'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeUser', true, 'Valider inscriptions'); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo sprintf('%s %s', helper::translate('Permissions'), helper::translate('Auto-inscription')); ?>
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeEdit', true, 'Éditer inscription'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeDelete', true, 'Effacer inscription'); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilAddSuscribeUser', true, 'Valider inscriptions'); ?>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,26 +1,26 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo sprintf('%s %s', helper::translate('Permissions'), helper::translate('Auto-inscription')); ?>·
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeEdit', true, 'Éditer inscription', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'edit'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeDelete', true, 'Effacer inscription', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'delete'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeUser', true, 'Valider inscriptions', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'user'])
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo sprintf('%s %s', helper::translate('Permissions'), helper::translate('Auto-inscription')); ?>·
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeEdit', true, 'Éditer inscription', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'edit'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeDelete', true, 'Effacer inscription', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'delete'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('profilEditSuscribeUser', true, 'Valider inscriptions', [
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'suscribe', 'user'])
]); ?>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,487 +1,503 @@
<?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 Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
class suscribe extends common
{
const VERSION = '2.0';
const REALNAME = 'Auto Inscription';
const DELETE = true;
const UPDATE = '0.0';
const DATADIRECTORY = ''; // Contenu localisé inclus par défaut (page.json et module.json)
const STATUS_EMAIL_AWAITING = 0;
const STATUS_EMAIL_VALID = 1;
const STATUS_ACCOUNT_AWAITING = 2;
const STATUS_ACCOUNT_VALID = 3;
public static $statusGroups = [
self::STATUS_EMAIL_AWAITING => 'Email non confirmé',
self::STATUS_EMAIL_VALID => 'Email valide',
self::STATUS_ACCOUNT_AWAITING => 'Email valide, en attente de confirmation',
self::STATUS_ACCOUNT_VALID => 'Email valide, compte activé',
];
public static $actions = [
'index' => self::GROUP_VISITOR,
'validate' => self::GROUP_VISITOR,
'config' => self::GROUP_EDITOR,
'users' => self::GROUP_EDITOR,
'delete' => self::GROUP_EDITOR,
'edit' => self::GROUP_EDITOR
];
public static $layout = [
'inputRowContainer1' => 'Un élément par ligne',
'inputRowContainer2' => 'Deux éléments par ligne',
'inputRowContainer4' => 'Quatre éléments par ligne',
];
public static $timeLimit = [
2 => '2 minutes',
5 => '5 minutes',
10 => '10 minutes'
];
public static $users = [];
public static $groups = [];
public static $userProfils = [];
public static $userProfilsComments = [];
/**
* Liste des utilisateurs en attente
*/
public function users()
{
$userIdsFirstnames = helper::arraycollumn($this->getData(['module', $this->getUrl(0), 'users']), 'firstname');
ksort($userIdsFirstnames);
foreach ($userIdsFirstnames as $userId => $userFirstname) {
self::$users[] = [
$userId,
$userFirstname . ' ' . $this->getData(['module', $this->getUrl(0), 'users', $userId, 'lastname']),
self::$statusGroups[$this->getData(['module', $this->getUrl(0), 'users', $userId, 'status'])],
helper::dateUTF8(date('Y-m-d G:i'), $this->getData(['module', $this->getUrl(0), 'users', $userId, 'timer'])),
template::button('registrationUserEdit' . $userId, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $userId,
'value' => template::ico('pencil')
]),
template::button('registrationUserDelete' . $userId, [
'class' => 'userDelete red',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $userId,
'value' => template::ico('cancel')
])
];
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Inscription en attente',
'view' => 'users'
]);
}
/**
* Édition
*/
public function edit()
{
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès refusé
if (
// L'utilisateur n'existe pas
$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]) === null
// Droit d'édition
and (
// Impossible de s'auto-éditer
(
$this->getUser('id') === 'user'
and $this->getUrl('group') <= self::GROUP_VISITOR
)
// Impossible d'éditer un autre utilisateur
or ($this->getUrl('group') < self::GROUP_EDITOR)
)
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true
&& $this->isPost()
) {
// Créer le user dans la base
$this->setData([
'user',
$this->getUrl(2),
[
'firstname' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'firstname']),
'forgot' => 0,
'group' => $this->getInput('registrationUserEditGroup', helper::FILTER_INT),
// Le profil vaut 0 pour les amdins et 1 pour les autres membres, profil par défaut.
'profil' => $this->getInput('registrationUserEditGroup', helper::FILTER_INT) === self::GROUP_ADMIN
? 0 : 1,
'lastname' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'lastname']),
'mail' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'mail']),
'password' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'password']),
'tags' => $this->getInput('registrationUserLabel', helper::FILTER_STRING_SHORT),
'connectFail' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'connectFail']),
'connectTimeout' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'connectTimeout']),
'accessUrl' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessUrl']),
'accessTimer' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessTimer']),
'accessCsrf' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessCsrf'])
]
]);
// Notifier le user uniquement si le groupe est membre au moins membre
if ($this->getInput('registrationUserEditGroup') >= 1) {
$this->sendMail(
$this->getData(['module', $this->getUrl(0), 'users', 'mail']),
'Approbation de l\'inscription',
'<p>' . $this->getdata(['module', $this->getUrl(0), 'config', 'mailValidateContent']) . '</p>',
null,
$this->getData(['config', 'smtp', 'from'])
);
}
// Supprimer le user de la base temporaire,
$this->deleteData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/users',
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Changement temporaire de libellé du groupe 0
self::$groups = self::$groupEdits;
self::$groups[self::GROUP_BANNED] = 'En attente d\'approbation';
// Profils disponibles
foreach ($this->getData(['profil']) as $profilId => $profilData) {
if ($profilId < self::GROUP_MEMBER) {
continue;
}
if ($profilId === self::GROUP_ADMIN) {
self::$userProfils[$profilId][self::GROUP_ADMIN] = $profilData['name'];
self::$userProfilsComments[$profilId][self::GROUP_ADMIN] = $profilData['comment'];
continue;
}
foreach ($profilData as $key => $value) {
self::$userProfils[$profilId][$key] = $profilData[$key]['name'];
self::$userProfilsComments[$profilId][$key] = $profilData[$key]['name'] . ' : ' . $profilData[$key]['comment'];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['module', $this->getUrl(0), 'users', 'firstname']) . ' ' . $this->getData(['user', $this->getUrl(0), 'lastname']),
'view' => 'edit'
]);
}
}
/**
* Suppression
*/
public function delete()
{
// Accès refusé
if (
// L'utilisateur n'existe pas
$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]) === null
// Groupe insuffisant
&& $this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Suppression
else {
$this->deleteData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/users',
'notification' => 'Utilisateur supprimé',
'state' => true
]);
}
}
/**
* Ajout
*/
public function index()
{
/**
* Traitement du formulaire
* Stocke les données du formulaire dans le module
* Envoie le mail de vérification de l'email
*/
// Soumission du formulaire
if ($this->isPost()) {
// Le domaine saisi est invalide si un filtre existe
if (
!empty($this->getData(['module', $this->getUrl(0), 'config', 'filter']))
) {
// Contrôler la validité du domaine saisi parmi les domaines valides
$email_to_check = $this->getInput('registrationAddMail', helper::FILTER_MAIL, true);
$valid_domains[] = strpos($this->getData(['module', $this->getUrl(0), 'config', 'filter']), ';') === false
? $this->getData(['module', $this->getUrl(0), 'config', 'filter'])
: explode(';', $this->getData(['module', $this->getUrl(0), 'config', 'filter']));
if (in_array(explode('@', $email_to_check)[1], $valid_domains) === false) {
self::$inputNotices['registrationAddMail'] = 'Ce domaine n\'est pas autorisé';
}
}
// Drapeau de contrôle des données saisies.
$check = true;
$sentMailtoUser = false;
// L'identifiant d'utilisateur est indisponible
$userId = $this->getInput('registrationAddId', helper::FILTER_ID, true);
if (is_array($this->getData(['user', $userId]))) {
self::$inputNotices['registrationAddId'] = 'Identifiant invalide';
$check = false;
}
// Le compte existe déjà
foreach ($this->getData(['user']) as $usersId => $user) {
if ($user['mail'] === $this->getInput('registrationAddMail', helper::FILTER_MAIL, true)) {
self::$inputNotices['registrationAddMail'] = 'Vous ne pouvez pas utilisez cette boite mail';
$check = false;
break;
}
}
// Données de l'utilisateur
$userFirstname = $this->getInput('registrationAddFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('registrationAddLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('registrationAddMail', helper::FILTER_MAIL, true);
// Pas de nom saisi
if (
empty($userFirstname) ||
empty($userLastname)
) {
$check = false;
}
// Si tout est ok
if ($check === true) {
// Enregistrement du compte dans les données du module
$auth = uniqid('', true);
$this->setData([
'module',
$this->getUrl(0),
'users',
$userId,
[
'firstname' => $userFirstname,
'lastname' => $userLastname,
'mail' => $userMail,
'password' => '',
// pas de groupe afin de le différencier dans la liste des users
'timer' => time(),
'auth' => $auth,
'status' => self::STATUS_EMAIL_AWAITING
]
]);
// Mail d'avertissement aux administrateurs
// Utilisateurs dans le groupe admin
$to = [];
foreach ($this->getData(['user']) as $key => $user) {
if ($user['group'] == self::GROUP_ADMIN) {
$to[] = $user['mail'];
}
}
// Envoi du mail à l'administrateur
if ($check && is_array($to)) {
$this->sendMail(
$to,
'Auto-inscription sur le site ' . $this->getData(['config', 'title']),
'<p>Un nouveau membre s\'est inscrit, son email est en attente de validation</p>' .
'<p><strong>Identifiant du compte :</strong> ' . $userId . ' (' . $userFirstname . ' ' . $userLastname . ')<br>' .
'<strong>Email :</strong> ' . $userMail . '</p>' .
'<a href="' . helper::baseUrl() . 'user/login/' . strip_tags(str_replace('/', '_', $this->getUrl(0) . '/users')) . '">Validation de l\'inscription</a>',
null,
$this->getData(['config', 'smtp', 'from'])
);
}
// Mail de confirmation à l'utilisateur
// forger le lien de vérification
$validateLink = helper::baseUrl(true) . $this->getUrl() . '/validate/' . $userId . '/' . $auth;
// Envoi
if ($check) {
$sentMailtoUser = $this->sendMail(
$userMail,
'Confirmation de votre inscription',
'<p>' . $this->getdata(['module', $this->getUrl(0), 'config', 'mailRegisterContent']) . '</p>' .
'<p><a href="' . $validateLink . '">Activer votre compte<a/>' . '</p>' .
'<p>ou copiez collez le lien suivant dans un navigateur : ' . $validateLink . '</p>'
,
null,
$this->getData(['config', 'smtp', 'from'])
);
}
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
//'redirect' => $validateLink,
'notification' => $sentMailtoUser ? "Un mail vous a été envoyé." : 'Quelque chose n\'a pas fonctionné !',
'state' => $sentMailtoUser ? true : false
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Inscription',
'view' => 'index',
'showBarEditButton' => true,
'showPageContent' => true
]);
}
/**
* Vérification de l'email
*/
public function validate()
{
// Soumission du formulaire
if ($this->isPost()) {
// Vérifie la session + l'id + le timer
$check = true;
$notification = 'Bienvenue sur le site ' . $this->getData(['config', 'title']);
$userId = $this->getUrl(2);
$auth = $this->getUrl(3);
// la validité du lien est dépassé
if (
(time() - $this->getData(['module', $this->getUrl(0), 'users', $userId, 'timer']))
>= $this->getdata(['module', $this->getUrl(0), 'config', 'timeOut'])
) {
$check = false;
$notification = 'La validité du lien est dépassée';
}
// La clé est incorrecte ou le compte n'est pas en attente de validation
if (
$check
&& $auth !== $this->getData(['module', $this->getUrl(0), 'users', $userId, 'auth'])
&& $this->getData(['module', $this->getUrl(0), 'users', $userId, 'status']) !== self::STATUS_EMAIL_AWAITING
) {
$check = false;
$notification = 'Données incorrectes !';
}
// Double vérification pour le mot de passe
if (
$check
&& $this->getInput('registrationValidPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('registrationValidConfirmPassword', helper::FILTER_STRING_SHORT, true)
) {
self::$inputNotices['registrationAddConfirmPassword'] = 'Les mots de passe ne sont pas identiques';
$check = false;
}
if ($check) {
if (
// Pas d'approbation par un administrateur
$this->getData(['module', $this->getUrl(0), 'config', 'approval']) === false
) {
// Créer le compte
$this->setData([
'user',
$userId,
[
'firstname' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'firstname']),
'lastname' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'lastname']),
'mail' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'mail']),
'password' => $this->getInput('registrationValidPassword', helper::FILTER_PASSWORD, true),
'group' => self::GROUP_MEMBER,
'profil' => 1,
'forgot' => 0,
'pseudo' => $userId,
'signature' => 1,
'language' => self::$siteContent,
]
]);
// Modifier le statut dans le module
$this->deleteData(['module', $this->getUrl(0), 'users', $userId]);
$notification = 'Votre inscription est confirmée';
} else {
// Approbation nécessaire
$this->setData(['module', $this->getUrl(0), 'users', $userId, 'status', self::STATUS_ACCOUNT_AWAITING]);
$notification = 'L\'inscription doit être approuvée par un administrateur';
}
}
// Valeurs en sortie
$this->addOutput([
'redirect' => $check ? helper::baseUrl() . $this->getdata(['module', $this->getUrl(0), 'config', 'pageSuccess']) : helper::baseUrl() . $this->getdata(['module', $this->getUrl(0), 'config', 'pageError']),
'notification' => $notification,
'state' => $check
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Saisie du mot de passe',
'view' => 'validate'
]);
}
/**
* Module de configuration
*/
public function config()
{
// Soumission du formulaire
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true
&& $this->isPost()
) {
// Lire les options et les enregistrer
$this->setData([
'module',
$this->getUrl(0),
'config',
[
'timeOut' => $this->getInput('registrationConfigTimeOut', helper::FILTER_INT) * 60,
'pageSuccess' => $this->getInput('registrationConfigSuccess'),
'pageError' => $this->getInput('registrationConfigError'),
'approval' => $this->getInput('registrationConfigState', helper::FILTER_BOOLEAN),
'mailRegisterContent' => $this->getInput('registrationconfigMailRegisterContent', null, true),
'mailValidateContent' => $this->getInput('registrationconfigMailValidateContent', null, true),
'layout' => $this->getInput('registrationConfigLayout'),
'filter' => $this->getInput('registrationConfigFilter', helper::FILTER_STRING_SHORT)
]
]);
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(),
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'config',
'vendor' => ['tinymce']
]);
}
}
<?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 Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
class suscribe extends common
{
const VERSION = '2.3';
const REALNAME = 'Auto Inscription';
const DELETE = true;
const UPDATE = '0.0';
const DATADIRECTORY = ''; // Contenu localisé inclus par défaut (page.json et module.json)
const STATUS_EMAIL_AWAITING = 0;
const STATUS_EMAIL_VALID = 1;
const STATUS_ACCOUNT_AWAITING = 2;
const STATUS_ACCOUNT_VALID = 3;
public static $statusGroups = [
self::STATUS_EMAIL_AWAITING => 'Email non confirmé',
self::STATUS_EMAIL_VALID => 'Email valide',
self::STATUS_ACCOUNT_AWAITING => 'Email valide, en attente de confirmation',
self::STATUS_ACCOUNT_VALID => 'Email valide, compte activé',
];
public static $actions = [
'index' => self::GROUP_VISITOR,
'validate' => self::GROUP_VISITOR,
'config' => self::GROUP_EDITOR,
'users' => self::GROUP_EDITOR,
'delete' => self::GROUP_EDITOR,
'edit' => self::GROUP_EDITOR
];
public static $layout = [
'inputRowContainer1' => 'Un élément par ligne',
'inputRowContainer2' => 'Deux éléments par ligne',
'inputRowContainer4' => 'Quatre éléments par ligne',
];
public static $timeLimit = [
2 => '2 minutes',
5 => '5 minutes',
10 => '10 minutes'
];
public static $users = [];
public static $groups = [];
public static $userProfils = [];
public static $userProfilsComments = [];
/**
* Liste des utilisateurs en attente
*/
public function users()
{
$userIdsFirstnames = helper::arraycollumn($this->getData(['module', $this->getUrl(0), 'users']), 'firstname');
ksort($userIdsFirstnames);
foreach ($userIdsFirstnames as $userId => $userFirstname) {
self::$users[] = [
$userId,
$userFirstname . ' ' . $this->getData(['module', $this->getUrl(0), 'users', $userId, 'lastname']),
self::$statusGroups[$this->getData(['module', $this->getUrl(0), 'users', $userId, 'status'])],
helper::dateUTF8(date('Y-m-d G:i'), $this->getData(['module', $this->getUrl(0), 'users', $userId, 'timer'])),
template::button('registrationUserEdit' . $userId, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $userId,
'value' => template::ico('pencil')
]),
template::button('registrationUserDelete' . $userId, [
'class' => 'userDelete red',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $userId,
'value' => template::ico('cancel')
])
];
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Inscription en attente',
'view' => 'users'
]);
}
/**
* Édition
*/
public function edit()
{
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès refusé
if (
// L'utilisateur n'existe pas
$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]) === null
// Droit d'édition
and (
// Impossible de s'auto-éditer
(
$this->getUser('id') === 'user'
and $this->getUrl('group') <= self::GROUP_VISITOR
)
// Impossible d'éditer un autre utilisateur
or ($this->getUrl('group') < self::GROUP_EDITOR)
)
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true
&& $this->isPost()
) {
// Créer le user dans la base
$this->setData([
'user',
$this->getUrl(2),
[
'firstname' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'firstname']),
'forgot' => 0,
'group' => $this->getInput('registrationUserEditGroup', helper::FILTER_INT),
// Le profil vaut 0 pour les amdins et 1 pour les autres membres, profil par défaut.
'profil' => $this->getInput('registrationUserEditGroup', helper::FILTER_INT) === self::GROUP_ADMIN
? 0 : 1,
'lastname' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'lastname']),
'mail' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'mail']),
'password' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'password']),
'tags' => $this->getInput('registrationUserLabel', helper::FILTER_STRING_SHORT),
'connectFail' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'connectFail']),
'connectTimeout' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'connectTimeout']),
'accessUrl' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessUrl']),
'accessTimer' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessTimer']),
'accessCsrf' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'accessCsrf'])
]
]);
// Notifier le user uniquement si le groupe est membre au moins membre
if ($this->getInput('registrationUserEditGroup') >= 1) {
$this->sendMail(
$this->getData(['module', $this->getUrl(0), 'users', 'mail']),
'Approbation de l\'inscription',
'<p>' . $this->getdata(['module', $this->getUrl(0), 'config', 'mailValidateContent']) . '</p>',
null,
$this->getData(['config', 'smtp', 'from'])
);
}
// Supprimer le user de la base temporaire,
$this->deleteData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/users',
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Changement temporaire de libellé du groupe 0
self::$groups = self::$groupEdits;
self::$groups[self::GROUP_BANNED] = 'En attente d\'approbation';
// Profils disponibles
foreach ($this->getData(['profil']) as $profilId => $profilData) {
if ($profilId < self::GROUP_MEMBER) {
continue;
}
if ($profilId === self::GROUP_ADMIN) {
self::$userProfils[$profilId][self::GROUP_ADMIN] = $profilData['name'];
self::$userProfilsComments[$profilId][self::GROUP_ADMIN] = $profilData['comment'];
continue;
}
foreach ($profilData as $key => $value) {
self::$userProfils[$profilId][$key] = $profilData[$key]['name'];
self::$userProfilsComments[$profilId][$key] = $profilData[$key]['name'] . ' : ' . $profilData[$key]['comment'];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['module', $this->getUrl(0), 'users', 'firstname']) . ' ' . $this->getData(['user', $this->getUrl(0), 'lastname']),
'view' => 'edit'
]);
}
}
/**
* Suppression
*/
public function delete()
{
// Accès refusé
if (
// L'utilisateur n'existe pas
$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]) === null
// Groupe insuffisant
&& $this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Suppression
else {
$this->deleteData(['module', $this->getUrl(0), 'users', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/users',
'notification' => 'Utilisateur supprimé',
'state' => true
]);
}
}
/**
* Ajout
*/
public function index()
{
/**
* Traitement du formulaire
* Stocke les données du formulaire dans le module
* Envoie le mail de vérification de l'email
*/
// Soumission du formulaire
if ($this->isPost()) {
// Contrôler la validité du domaine saisi parmi les domaines valides
$email_to_check = $this->getInput('registrationAddMail', helper::FILTER_MAIL, true);
// Le domaine saisi est invalide si un filtre existe
if (
empty($this->getData(['module', $this->getUrl(0), 'config', 'filter'])) === true &&
empty($email_to_check) === true
) {
// Récupérer la liste des domaines valides depuis la configuration et supprimer les espaces autour
$filter = trim($this->getData(['module', $this->getUrl(0), 'config', 'filter']));
// Vérifier si la liste contient plusieurs domaines ou un seul, puis supprimer les espaces pour chaque domaine
$valid_domains = strpos($filter, ';') === false
? [trim($filter)] // Si un seul domaine, on supprime les espaces et on le met dans un tableau
: array_map('trim', explode(';', $filter)); // Si plusieurs domaines, on les explose en tableau et supprime les espaces
// Extraire le domaine de l'adresse email à vérifier
$email_domain = explode('@', $email_to_check)[1];
// Vérifier si le domaine de l'email est dans la liste des domaines valides
if (!in_array($email_domain, $valid_domains)) {
self::$inputNotices['registrationAddMail'] = 'Ce domaine n\'est pas autorisé';
}
}
// Email valide, on continue le traitement
if (self::$inputNotices === []) {
// Drapeau de contrôle des données saisies.
$check = true;
$sentMailtoUser = false;
// L'identifiant d'utilisateur est indisponible
$userId = $this->getInput('registrationAddId', helper::FILTER_ID, true);
if (is_array($this->getData(['user', $userId]))) {
self::$inputNotices['registrationAddId'] = 'Identifiant invalide';
$check = false;
}
// Le compte existe déjà
foreach ($this->getData(['user']) as $usersId => $user) {
if ($user['mail'] === $this->getInput('registrationAddMail', helper::FILTER_MAIL, true)) {
self::$inputNotices['registrationAddMail'] = 'Vous ne pouvez pas utilisez cette boite mail';
$check = false;
break;
}
}
// Données de l'utilisateur
$userFirstname = $this->getInput('registrationAddFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('registrationAddLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('registrationAddMail', helper::FILTER_MAIL, true);
// Pas de nom saisi
if (
empty($userFirstname) ||
empty($userLastname)
) {
$check = false;
}
// Si tout est ok
if ($check === true) {
// Enregistrement du compte dans les données du module
$auth = uniqid('', true);
$this->setData([
'module',
$this->getUrl(0),
'users',
$userId,
[
'firstname' => $userFirstname,
'lastname' => $userLastname,
'mail' => $userMail,
'password' => '',
// pas de groupe afin de le différencier dans la liste des users
'timer' => time(),
'auth' => $auth,
'status' => self::STATUS_EMAIL_AWAITING
]
]);
// Mail d'avertissement aux administrateurs
// Utilisateurs dans le groupe admin
$to = [];
foreach ($this->getData(['user']) as $key => $user) {
if ($user['group'] == self::GROUP_ADMIN) {
$to[] = $user['mail'];
}
}
// Envoi du mail à l'administrateur
if ($check && is_array($to)) {
$this->sendMail(
$to,
'Auto-inscription sur le site ' . $this->getData(['config', 'title']),
'<p>Un nouveau membre s\'est inscrit, son email est en attente de validation</p>' .
'<p><strong>Identifiant du compte :</strong> ' . $userId . ' (' . $userFirstname . ' ' . $userLastname . ')<br>' .
'<strong>Email :</strong> ' . $userMail . '</p>' .
'<a href="' . helper::baseUrl() . 'user/login/' . strip_tags(str_replace('/', '_', $this->getUrl(0) . '/users')) . '">Validation de l\'inscription</a>',
null,
$this->getData(['config', 'smtp', 'from'])
);
}
// Mail de confirmation à l'utilisateur
// forger le lien de vérification
$validateLink = helper::baseUrl(true) . $this->getUrl() . '/validate/' . $userId . '/' . $auth;
// Envoi
if ($check) {
$sentMailtoUser = $this->sendMail(
$userMail,
'Confirmation de votre inscription',
'<p>' . $this->getdata(['module', $this->getUrl(0), 'config', 'mailRegisterContent']) . '</p>' .
'<p><a href="' . $validateLink . '">Activer votre compte<a/>' . '</p>' .
'<p>ou copiez collez le lien suivant dans un navigateur : ' . $validateLink . '</p>'
,
null,
$this->getData(['config', 'smtp', 'from'])
);
}
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
//'redirect' => $validateLink,
'notification' => $sentMailtoUser ? "Un mail vous a été envoyé." : 'Quelque chose n\'a pas fonctionné !',
'state' => $sentMailtoUser ? true : false
]);
}
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Inscription',
'view' => 'index',
'showBarEditButton' => true,
'showPageContent' => true
]);
}
/**
* Vérification de l'email
*/
public function validate()
{
// Soumission du formulaire
if ($this->isPost()) {
// Vérifie la session + l'id + le timer
$check = true;
$notification = 'Bienvenue sur le site ' . $this->getData(['config', 'title']);
$userId = $this->getUrl(2);
$auth = $this->getUrl(3);
// la validité du lien est dépassé
if (
(time() - $this->getData(['module', $this->getUrl(0), 'users', $userId, 'timer']))
>= $this->getdata(['module', $this->getUrl(0), 'config', 'timeOut'])
) {
$check = false;
$notification = 'La validité du lien est dépassée';
}
// La clé est incorrecte ou le compte n'est pas en attente de validation
if (
$check
&& $auth !== $this->getData(['module', $this->getUrl(0), 'users', $userId, 'auth'])
&& $this->getData(['module', $this->getUrl(0), 'users', $userId, 'status']) !== self::STATUS_EMAIL_AWAITING
) {
$check = false;
$notification = 'Données incorrectes !';
}
// Double vérification pour le mot de passe
if (
$check
&& $this->getInput('registrationValidPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('registrationValidConfirmPassword', helper::FILTER_STRING_SHORT, true)
) {
self::$inputNotices['registrationAddConfirmPassword'] = 'Les mots de passe ne sont pas identiques';
$check = false;
}
if ($check) {
if (
// Pas d'approbation par un administrateur
$this->getData(['module', $this->getUrl(0), 'config', 'approval']) === false
) {
// Créer le compte
$this->setData([
'user',
$userId,
[
'firstname' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'firstname']),
'lastname' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'lastname']),
'mail' => $this->getData(['module', $this->getUrl(0), 'users', $userId, 'mail']),
'password' => $this->getInput('registrationValidPassword', helper::FILTER_PASSWORD, true),
'group' => self::GROUP_MEMBER,
'profil' => 1,
'forgot' => 0,
'pseudo' => $userId,
'signature' => 1,
'language' => self::$siteContent,
]
]);
// Modifier le statut dans le module
$this->deleteData(['module', $this->getUrl(0), 'users', $userId]);
$notification = 'Votre inscription est confirmée';
} else {
// Approbation nécessaire
$this->setData(['module', $this->getUrl(0), 'users', $userId, 'status', self::STATUS_ACCOUNT_AWAITING]);
$notification = 'L\'inscription doit être approuvée par un administrateur';
}
}
// Valeurs en sortie
$this->addOutput([
'redirect' => $check ? helper::baseUrl() . $this->getdata(['module', $this->getUrl(0), 'config', 'pageSuccess']) : helper::baseUrl() . $this->getdata(['module', $this->getUrl(0), 'config', 'pageError']),
'notification' => $notification,
'state' => $check
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Saisie du mot de passe',
'view' => 'validate'
]);
}
/**
* Module de configuration
*/
public function config()
{
// Soumission du formulaire
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true
&& $this->isPost()
) {
// Lire les options et les enregistrer
$this->setData([
'module',
$this->getUrl(0),
'config',
[
'timeOut' => $this->getInput('registrationConfigTimeOut', helper::FILTER_INT) * 60,
'pageSuccess' => $this->getInput('registrationConfigSuccess'),
'pageError' => $this->getInput('registrationConfigError'),
'approval' => $this->getInput('registrationConfigState', helper::FILTER_BOOLEAN),
'mailRegisterContent' => $this->getInput('registrationconfigMailRegisterContent', null, true),
'mailValidateContent' => $this->getInput('registrationconfigMailValidateContent', null, true),
'layout' => $this->getInput('registrationConfigLayout'),
'filter' => $this->getInput('registrationConfigFilter', helper::FILTER_STRING_SHORT)
]
]);
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(),
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'config',
'vendor' => ['tinymce']
]);
}
}

View File

@ -1,21 +1,21 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
*/
textarea .editorWysiwyg {
height : 100px;
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
*/
textarea .editorWysiwyg {
height : 100px;
}

View File

@ -1,103 +1,103 @@
<?php echo template::formOpen('registrationConfig'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('registrationConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset7">
<?php echo template::button('registrationConfigBack', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/users',
'value' => 'Inscriptions'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('registrationConfigSubmit', [
'class' => 'green'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<div class="row">
<div class="col4">
<?php echo template::select('registrationConfigLayout', $module::$layout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('registrationConfigSuccess', helper::arraycollumn($this->getData(['page']), 'title', 'SORT_ASC'), [
'label' => 'Redirection après confirmation',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'pageSuccess'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('registrationConfigError', helper::arraycollumn($this->getData(['page']), 'title', 'SORT_ASC'), [
'label' => 'Redirection après erreur',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'pageError'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Communication</h4>
<div class="row">
<div class="col6">
<?php echo template::select('registrationConfigTimeOut', $module::$timeLimit, [
'label' => 'Validité du lien',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeOut']) / 60
]); ?>
</div>
<div class="col6">
<?php echo template::text('registrationConfigFilter', [
'label' => 'Domaines acceptés',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'filter']),
'help' => 'Champ vide sinon limitation à des domaines spécifiques, le séparateur est ;'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php $messageDefault = '<p>Confirmez votre inscription en cliquant sur ce lien dans les ... minutes.</p>'; ?>
<?php echo template::textarea('registrationconfigMailRegisterContent', [
'label' => 'Corps du mail de confirmation',
'value' => !empty($this->getData(['module', $this->getUrl(0), 'config', 'mailRegisterContent'])) ? $this->getData(['module', $this->getUrl(0), 'config', 'mailRegisterContent']) : $messageDefault,
'class' => 'editorWysiwyg',
'help' => 'Précisez la durée de validité. Le lien sera inséré après ces explications.'
]); ?>
</div>
</div>
<div class="row">
<div class="col6 verticalAlignMiddle">
<?php echo template::checkbox('registrationConfigState', true, 'Approbation préalable', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'approval']),
'help' => 'Les comptes sont inactifs tant que les inscriptions ne sont pas approuvées par un administrateur.',
'check' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php $messageDefault = '<p>Votre inscription a été approuvée par un administrateur.</p>'; ?>
<?php echo template::textarea('registrationconfigMailValidateContent', [
'label' => 'Corps du mail d\'approbation',
'value' => !empty($this->getData(['module', $this->getUrl(0), 'config', 'mailValidateContent'])) ? $this->getData(['module', $this->getUrl(0), 'config', 'mailValidateContent']) : $messageDefault,
'class' => 'editorWysiwyg'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="moduleVersion">Version <?php echo $module::VERSION; ?>
<?php echo template::formOpen('registrationConfig'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('registrationConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset7">
<?php echo template::button('registrationConfigBack', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/users',
'value' => 'Inscriptions'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('registrationConfigSubmit', [
'class' => 'green'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<div class="row">
<div class="col4">
<?php echo template::select('registrationConfigLayout', $module::$layout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('registrationConfigSuccess', helper::arraycollumn($this->getData(['page']), 'title', 'SORT_ASC'), [
'label' => 'Redirection après confirmation',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'pageSuccess'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('registrationConfigError', helper::arraycollumn($this->getData(['page']), 'title', 'SORT_ASC'), [
'label' => 'Redirection après erreur',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'pageError'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Communication</h4>
<div class="row">
<div class="col6">
<?php echo template::select('registrationConfigTimeOut', $module::$timeLimit, [
'label' => 'Validité du lien',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeOut']) / 60
]); ?>
</div>
<div class="col6">
<?php echo template::text('registrationConfigFilter', [
'label' => 'Domaines acceptés',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'filter']),
'help' => 'Champ vide sinon limitation à des domaines spécifiques, le séparateur est ;'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php $messageDefault = '<p>Confirmez votre inscription en cliquant sur ce lien dans les ... minutes.</p>'; ?>
<?php echo template::textarea('registrationconfigMailRegisterContent', [
'label' => 'Corps du mail de confirmation',
'value' => !empty($this->getData(['module', $this->getUrl(0), 'config', 'mailRegisterContent'])) ? $this->getData(['module', $this->getUrl(0), 'config', 'mailRegisterContent']) : $messageDefault,
'class' => 'editorWysiwyg',
'help' => 'Précisez la durée de validité. Le lien sera inséré après ces explications.'
]); ?>
</div>
</div>
<div class="row">
<div class="col6 verticalAlignMiddle">
<?php echo template::checkbox('registrationConfigState', true, 'Approbation préalable', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'approval']),
'help' => 'Les comptes sont inactifs tant que les inscriptions ne sont pas approuvées par un administrateur.',
'check' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php $messageDefault = '<p>Votre inscription a été approuvée par un administrateur.</p>'; ?>
<?php echo template::textarea('registrationconfigMailValidateContent', [
'label' => 'Corps du mail d\'approbation',
'value' => !empty($this->getData(['module', $this->getUrl(0), 'config', 'mailValidateContent'])) ? $this->getData(['module', $this->getUrl(0), 'config', 'mailValidateContent']) : $messageDefault,
'class' => 'editorWysiwyg'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="moduleVersion">Version <?php echo $module::VERSION; ?>
</div>

View File

@ -1,21 +1,21 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
*/
#registrationUserEditProfil1Wrapper,
#registrationUserEditProfil2Wrapper {
padding: 0;
}
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
*/
#registrationUserEditProfil1Wrapper,
#registrationUserEditProfil2Wrapper {
padding: 0;
}

View File

@ -1,31 +1,31 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Droits des groupes
*/
$(document).ready(function () {
$(".registrationUserEditGroupProfil").hide();
$(".registrationUserCommentProfil").hide();
$("#registrationUserEditGroupProfil" + $("#registrationUserEditGroup").val()).show();
$("#registrationUserCommentProfil" + $("#registrationUserEditGroup").val()).show();
$("#registrationUserEditGroup").on("change", function () {
$(".registrationUserEditGroupProfil").hide();
$(".registrationUserCommentProfil").hide();
$("#registrationUserEditGroupProfil" + $(this).val()).show();
$("#registrationUserCommentProfil" + $(this).val()).show();
});
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Droits des groupes
*/
$(document).ready(function () {
$(".registrationUserEditGroupProfil").hide();
$(".registrationUserCommentProfil").hide();
$("#registrationUserEditGroupProfil" + $("#registrationUserEditGroup").val()).show();
$("#registrationUserCommentProfil" + $("#registrationUserEditGroup").val()).show();
$("#registrationUserEditGroup").on("change", function () {
$(".registrationUserEditGroupProfil").hide();
$(".registrationUserCommentProfil").hide();
$("#registrationUserEditGroupProfil" + $(this).val()).show();
$("#registrationUserCommentProfil" + $(this).val()).show();
});
});

View File

@ -1,140 +1,140 @@
<?php echo template::formOpen('registrationUserEditForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('registrationUserEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->geturl(0) . '/users',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('registrationUserEditSubmit', [
'class' => 'green'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Confirmation de l'inscription</h4>
<div class="row">
<div class="col12">
<div class="row">
<div class="col6">
<?php echo template::text('registrationUserEditFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'firstname']),
'disabled' => true
]); ?>
</div>
<div class="col6">
<?php echo template::text('registrationUserEditLastname', [
'autocomplete' => 'off',
'label' => 'Nom',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'lastname']),
'disabled' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::mail('registrationUserEditMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'mail']),
'disabled' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::text('registrationUserState', [
'label' => 'État de l\'inscription',
'value' => $module::$statusGroups[$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'status'])],
'disabled' => true,
'help' => 'En attente : le mail n\'a pas encore été validé<br>Email validé : approbation nécessaire.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('registrationUsertimer', [
'label' => 'Date de demande',
'value' => helper::dateUTF8(date('Y-m-d G:i'), $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'timer'])),
'disabled' => true
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::text('registrationUserLabel', [
'label' => 'Étiquette'
]); ?>
</div>
<div class="col4">
<?php if ($this->getUser('group') === self::GROUP_ADMIN): ?>
<?php echo template::select('registrationUserEditGroup', $module::$groups, [
'disabled' => ($this->getUrl(2) === $this->getUser('id')),
'help' => ($this->getUrl(2) === $this->getUser('id') ? 'Impossible de modifier votre propre groupe.' : ''),
'label' => 'Groupe',
'selected' => $this->getData(['module', $this->getUrl(0), 'registrationUsers', $this->getUrl(2), 'status'])
]); ?>
<?php endif; ?>
</div>
<div class="col4">
<div class="registrationUserEditGroupProfil"
id="registrationUserEditGroupProfil<?php echo self::GROUP_MEMBER; ?>">
<?php echo template::select('registrationUserEditProfil' . self::GROUP_MEMBER, $module::$userProfils[self::GROUP_MEMBER], [
'label' => 'Profil',
'selected' => $this->getData(['user', $this->getUrl(2), 'profil']),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN,
]); ?>
</div>
<div class="registrationUserEditGroupProfil"
id="registrationUserEditGroupProfil<?php echo self::GROUP_EDITOR; ?>">
<?php echo template::select('registrationUserEditProfil' . self::GROUP_EDITOR, $module::$userProfils[self::GROUP_EDITOR], [
'label' => 'Profil',
'selected' => $this->getData(['user', $this->getUrl(2), 'profil']),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN,
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div id="registrationUserCommentProfil<?php echo self::GROUP_MEMBER; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_MEMBER, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_MEMBER]),
'readonly' => true,
]);
?>
</div>
<div id="registrationUserCommentProfil<?php echo self::GROUP_EDITOR; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_EDITOR, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_EDITOR]),
'readonly' => true,
]);
?>
</div>
<div id="registrationUserCommentProfil<?php echo self::GROUP_ADMIN; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_ADMIN, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_ADMIN]),
'readonly' => true,
]);
?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formOpen('registrationUserEditForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('registrationUserEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->geturl(0) . '/users',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('registrationUserEditSubmit', [
'class' => 'green'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Confirmation de l'inscription</h4>
<div class="row">
<div class="col12">
<div class="row">
<div class="col6">
<?php echo template::text('registrationUserEditFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'firstname']),
'disabled' => true
]); ?>
</div>
<div class="col6">
<?php echo template::text('registrationUserEditLastname', [
'autocomplete' => 'off',
'label' => 'Nom',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'lastname']),
'disabled' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::mail('registrationUserEditMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique',
'value' => $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'mail']),
'disabled' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::text('registrationUserState', [
'label' => 'État de l\'inscription',
'value' => $module::$statusGroups[$this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'status'])],
'disabled' => true,
'help' => 'En attente : le mail n\'a pas encore été validé<br>Email validé : approbation nécessaire.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('registrationUsertimer', [
'label' => 'Date de demande',
'value' => helper::dateUTF8(date('Y-m-d G:i'), $this->getData(['module', $this->getUrl(0), 'users', $this->getUrl(2), 'timer'])),
'disabled' => true
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::text('registrationUserLabel', [
'label' => 'Étiquette'
]); ?>
</div>
<div class="col4">
<?php if ($this->getUser('group') === self::GROUP_ADMIN): ?>
<?php echo template::select('registrationUserEditGroup', $module::$groups, [
'disabled' => ($this->getUrl(2) === $this->getUser('id')),
'help' => ($this->getUrl(2) === $this->getUser('id') ? 'Impossible de modifier votre propre groupe.' : ''),
'label' => 'Groupe',
'selected' => $this->getData(['module', $this->getUrl(0), 'registrationUsers', $this->getUrl(2), 'status'])
]); ?>
<?php endif; ?>
</div>
<div class="col4">
<div class="registrationUserEditGroupProfil"
id="registrationUserEditGroupProfil<?php echo self::GROUP_MEMBER; ?>">
<?php echo template::select('registrationUserEditProfil' . self::GROUP_MEMBER, $module::$userProfils[self::GROUP_MEMBER], [
'label' => 'Profil',
'selected' => $this->getData(['user', $this->getUrl(2), 'profil']),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN,
]); ?>
</div>
<div class="registrationUserEditGroupProfil"
id="registrationUserEditGroupProfil<?php echo self::GROUP_EDITOR; ?>">
<?php echo template::select('registrationUserEditProfil' . self::GROUP_EDITOR, $module::$userProfils[self::GROUP_EDITOR], [
'label' => 'Profil',
'selected' => $this->getData(['user', $this->getUrl(2), 'profil']),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN,
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div id="registrationUserCommentProfil<?php echo self::GROUP_MEMBER; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_MEMBER, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_MEMBER]),
'readonly' => true,
]);
?>
</div>
<div id="registrationUserCommentProfil<?php echo self::GROUP_EDITOR; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_EDITOR, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_EDITOR]),
'readonly' => true,
]);
?>
</div>
<div id="registrationUserCommentProfil<?php echo self::GROUP_ADMIN; ?>"
class="col12 registrationUserCommentProfil">
<?php echo template::textarea('registrationUserEditProfilComment' . self::GROUP_ADMIN, [
'label' => 'Commentaire',
'value' => implode("\n", $module::$userProfilsComments[self::GROUP_ADMIN]),
'readonly' => true,
]);
?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -1,37 +1,37 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
.inputRowContainer1,
.inputRowContainer2,
.inputRowContainer4,
.inputColContainer {
display: grid;
gap: 10px; /* Espacement entre les inputs */
}
/* En lignes */
.inputRowContainer1 {
grid-template-columns: repeat(1, 1fr); /* 3 colonnes de largeur égale */
}
.inputRowContainer2 {
grid-template-columns: repeat(2, 1fr); /* 3 colonnes de largeur égale */
}
.inputRowContainer4 {
grid-template-columns: repeat(4, 1fr); /* 3 colonnes de largeur égale */
}
.inputColContainer {
grid-template-rows: repeat(50px, auto); /* 3 rangées ajustées à la hauteur des contenus */
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
.inputRowContainer1,
.inputRowContainer2,
.inputRowContainer4,
.inputColContainer {
display: grid;
gap: 10px; /* Espacement entre les inputs */
}
/* En lignes */
.inputRowContainer1 {
grid-template-columns: repeat(1, 1fr); /* 3 colonnes de largeur égale */
}
.inputRowContainer2 {
grid-template-columns: repeat(2, 1fr); /* 3 colonnes de largeur égale */
}
.inputRowContainer4 {
grid-template-columns: repeat(4, 1fr); /* 3 colonnes de largeur égale */
}
.inputColContainer {
grid-template-rows: repeat(50px, auto); /* 3 rangées ajustées à la hauteur des contenus */
}

View File

@ -1,47 +1,47 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Affichage de l'id en simulant FILTER_ID
*/
$("#registrationAddId").on("change keydown keyup", function(event) {
var userId = $(this).val();
if(
event.keyCode !== 8 // BACKSPACE
&& event.keyCode !== 37 // LEFT
&& event.keyCode !== 39 // RIGHT
&& event.keyCode !== 46 // DELETE
&& window.getSelection().toString() !== userId // Texte sélectionné
) {
var searchReplace = {
"á": "a", "à": "a", "â": "a", "ä": "a", "ã": "a", "å": "a", "ç": "c", "é": "e", "è": "e", "ê": "e", "ë": "e", "í": "i", "ì": "i", "î": "i", "ï": "i", "ñ": "n", "ó": "o", "ò": "o", "ô": "o", "ö": "o", "õ": "o", "ú": "u", "ù": "u", "û": "u", "ü": "u", "ý": "y", "ÿ": "y",
"Á": "A", "À": "A", "Â": "A", "Ä": "A", "Ã": "A", "Å": "A", "Ç": "C", "É": "E", "È": "E", "Ê": "E", "Ë": "E", "Í": "I", "Ì": "I", "Î": "I", "Ï": "I", "Ñ": "N", "Ó": "O", "Ò": "O", "Ô": "O", "Ö": "O", "Õ": "O", "Ú": "U", "Ù": "U", "Û": "U", "Ü": "U", "Ý": "Y", "Ÿ": "Y",
"'": "-", "\"": "-", " ": "-"
};
userId = userId.replace(/[áàâäãåçéèêëíìîïñóòôöõúùûüýÿ'" ]/ig, function(match) {
return searchReplace[match];
});
userId = userId.replace(/[^a-z0-9-]/ig, "");
$(this).val(userId);
}
});
/**
* Droits des groupes
*/
$("#registrationAddGroup").on("change", function() {
$(".registrationAddGroupDescription").hide();
$("#registrationAddGroupDescription" + $(this).val()).show();
}).trigger("change");
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Affichage de l'id en simulant FILTER_ID
*/
$("#registrationAddId").on("change keydown keyup", function(event) {
var userId = $(this).val();
if(
event.keyCode !== 8 // BACKSPACE
&& event.keyCode !== 37 // LEFT
&& event.keyCode !== 39 // RIGHT
&& event.keyCode !== 46 // DELETE
&& window.getSelection().toString() !== userId // Texte sélectionné
) {
var searchReplace = {
"á": "a", "à": "a", "â": "a", "ä": "a", "ã": "a", "å": "a", "ç": "c", "é": "e", "è": "e", "ê": "e", "ë": "e", "í": "i", "ì": "i", "î": "i", "ï": "i", "ñ": "n", "ó": "o", "ò": "o", "ô": "o", "ö": "o", "õ": "o", "ú": "u", "ù": "u", "û": "u", "ü": "u", "ý": "y", "ÿ": "y",
"Á": "A", "À": "A", "Â": "A", "Ä": "A", "Ã": "A", "Å": "A", "Ç": "C", "É": "E", "È": "E", "Ê": "E", "Ë": "E", "Í": "I", "Ì": "I", "Î": "I", "Ï": "I", "Ñ": "N", "Ó": "O", "Ò": "O", "Ô": "O", "Ö": "O", "Õ": "O", "Ú": "U", "Ù": "U", "Û": "U", "Ü": "U", "Ý": "Y", "Ÿ": "Y",
"'": "-", "\"": "-", " ": "-"
};
userId = userId.replace(/[áàâäãåçéèêëíìîïñóòôöõúùûüýÿ'" ]/ig, function(match) {
return searchReplace[match];
});
userId = userId.replace(/[^a-z0-9-]/ig, "");
$(this).val(userId);
}
});
/**
* Droits des groupes
*/
$("#registrationAddGroup").on("change", function() {
$(".registrationAddGroupDescription").hide();
$("#registrationAddGroupDescription" + $(this).val()).show();
}).trigger("change");

View File

@ -1,29 +1,29 @@
<?php echo template::formOpen('registrationAddForm'); ?>
<div class="<?php echo $this->getData(['module', $this->getUrl(0), 'config', 'layout']); ?>">
<?php echo template::text('registrationAddFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom'
]); ?>
<?php echo template::text('registrationAddLastname', [
'autocomplete' => 'off',
'label' => 'Nom'
]); ?>
<?php echo template::text('registrationAddId', [
'autocomplete' => 'off',
'label' => 'Identifiant de connexion'
]); ?>
<?php echo template::mail('registrationAddMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique'
]); ?>
</div>
<div class='submitContainer'>
<div class="row">
<div class="col2 offset10">
<?php echo template::submit('registrationAddSubmit', [
'value' => 'Envoyer'
]); ?>
</div>
</div>
</div>
<?php echo template::formOpen('registrationAddForm'); ?>
<div class="<?php echo $this->getData(['module', $this->getUrl(0), 'config', 'layout']); ?>">
<?php echo template::text('registrationAddFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom'
]); ?>
<?php echo template::text('registrationAddLastname', [
'autocomplete' => 'off',
'label' => 'Nom'
]); ?>
<?php echo template::text('registrationAddId', [
'autocomplete' => 'off',
'label' => 'Identifiant de connexion'
]); ?>
<?php echo template::mail('registrationAddMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique'
]); ?>
</div>
<div class='submitContainer'>
<div class="row">
<div class="col2 offset10">
<?php echo template::submit('registrationAddSubmit', [
'value' => 'Envoyer'
]); ?>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -1,17 +1,17 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -1,21 +1,21 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Confirmation de suppression
*/
$(".registrationUserDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cet utilisateur ?", function() {
$(location).attr("href", _this.attr("href"));
});
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
/**
* Confirmation de suppression
*/
$(".registrationUserDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cet utilisateur ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

View File

@ -1,15 +1,15 @@
<div class="row">
<div class="col1">
<?php echo template::button('registrationUserBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
</div>
<?php if($module::$users): ?>
<?php echo template::table([3, 3, 2,21, 1, 1], $module::$users, ['Identifiant', 'Nom', 'Etat', 'Date', '', '']); ?>
<?php else: ?>
<?php echo template::speech('Pas d\'inscription en attente.'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('registrationUserBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
</div>
<?php if($module::$users): ?>
<?php echo template::table([3, 3, 2,21, 1, 1], $module::$users, ['Identifiant', 'Nom', 'Etat', 'Date', '', '']); ?>
<?php else: ?>
<?php echo template::speech('Pas d\'inscription en attente.'); ?>
<?php endif; ?>

View File

@ -1,34 +1,34 @@
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
.inputRowContainer1,
.inputRowContainer2,
.inputRowContainer4,
.inputColContainer {
display: grid;
gap: 10px;
}
/* En lignes */
.inputRowContainer1 {
grid-template-columns: repeat(1, 1fr);
}
.inputRowContainer2 {
grid-template-columns: repeat(2, 1fr);
}
.inputRowContainer4 {
grid-template-columns: repeat(2, 1fr);
/**
* 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 CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.com/
*/
.inputRowContainer1,
.inputRowContainer2,
.inputRowContainer4,
.inputColContainer {
display: grid;
gap: 10px;
}
/* En lignes */
.inputRowContainer1 {
grid-template-columns: repeat(1, 1fr);
}
.inputRowContainer2 {
grid-template-columns: repeat(2, 1fr);
}
.inputRowContainer4 {
grid-template-columns: repeat(2, 1fr);
}

View File

@ -1,23 +1,23 @@
<?php echo template::formOpen('registrationValidForm'); ?>
<h3>Email confirmé</h3>
<div class="<?php echo $this->getData(['module',$this->getUrl(0),'config','layout']); ?>">
<?php echo template::password('registrationValidPassword', [
'autocomplete' => 'off',
'label' => 'Mot de passe'
]); ?>
<?php echo template::password('registrationValidConfirmPassword', [
'autocomplete' => 'off',
'label' => 'Confirmation du mot de passe'
]); ?>
</div>
<div class='submitContainer'>
<div class="row">
<div class="col2 offset10">
<?php echo template::submit('registrationValidSubmit', [
'value' => 'Envoyer',
'class' => 'green'
]); ?>
</div>
</div>
</div>
<?php echo template::formOpen('registrationValidForm'); ?>
<h3>Email confirmé</h3>
<div class="<?php echo $this->getData(['module',$this->getUrl(0),'config','layout']); ?>">
<?php echo template::password('registrationValidPassword', [
'autocomplete' => 'off',
'label' => 'Mot de passe'
]); ?>
<?php echo template::password('registrationValidConfirmPassword', [
'autocomplete' => 'off',
'label' => 'Confirmation du mot de passe'
]); ?>
</div>
<div class='submitContainer'>
<div class="row">
<div class="col2 offset10">
<?php echo template::submit('registrationValidSubmit', [
'value' => 'Envoyer',
'class' => 'green'
]); ?>
</div>
</div>
</div>
<?php echo template::formClose(); ?>