Compare commits
255 Commits
Author | SHA1 | Date | |
---|---|---|---|
e6d044d0e1 | |||
e596f5eef6 | |||
db2b6bc518 | |||
130b88ace1 | |||
9df1fe8be2 | |||
0f71d820c5 | |||
a8891b310f | |||
59de6bc32f | |||
3a25c33e3a | |||
eff57bf0ab | |||
20c09d8b0a | |||
a634445dde | |||
4c88d7a71d | |||
bb9b8b086f | |||
61752a9a51 | |||
889e2754fc | |||
77b241c69f | |||
442b84a99d | |||
09f9f6bdd6 | |||
5eace20e26 | |||
18df3848f8 | |||
7b9d145533 | |||
75ad5853cf | |||
7862815f1f | |||
a87d439282 | |||
509c1d6365 | |||
e641ec1c03 | |||
3dec8a8ce5 | |||
54f0b0c6e3 | |||
931e59db2e | |||
cae0e6c8fb | |||
afee77b1e7 | |||
cf8963248e | |||
22af8ac751 | |||
2d4385f038 | |||
c4bb124bea | |||
a474a41402 | |||
e9f65a1e22 | |||
8183b0bb0b | |||
585c888007 | |||
d0997ccbf9 | |||
1a6bfab54b | |||
23f38a606f | |||
f1e1989c97 | |||
9bb5793720 | |||
64443322a0 | |||
76258c835f | |||
dc81614114 | |||
8dc1adc28a | |||
65eac4ac4a | |||
a8f70dc73a | |||
02aeb6ec22 | |||
5bdb38dfec | |||
5700200bc3 | |||
4ffca0e34a | |||
f4553110e1 | |||
bf3b1f9cb0 | |||
05d8ae9e0b | |||
6128d0778d | |||
c38bd7d12f | |||
cd509dfcb1 | |||
5ab8efe72e | |||
6cf6a8d6b2 | |||
daaf309b4d | |||
2d5c395aec | |||
5d5b1e3140 | |||
8aa24e50ab | |||
8574970bb0 | |||
89e6e12748 | |||
9234b76062 | |||
08c1619162 | |||
576f349b4a | |||
be6eaa748e | |||
1dc7b08d2e | |||
35521766cd | |||
c8ee063963 | |||
f0aba44ddb | |||
e6236e5de2 | |||
e5629de660 | |||
92d3da27a3 | |||
1fd0c5492f | |||
bab06033ed | |||
f7cf0f94fc | |||
c244651b62 | |||
beb58da3bd | |||
8756162428 | |||
511a6ff0bb | |||
4175ff828d | |||
087b5d9999 | |||
fea1c40a4b | |||
2dce24f9f2 | |||
0e0fd23913 | |||
0eab6c9049 | |||
ca7ce4e857 | |||
510afbe8f1 | |||
c89a64ca7f | |||
9280d59aac | |||
3accdc135b | |||
3d31ce5e55 | |||
8c60eba918 | |||
b182c2ec90 | |||
523f30027a | |||
f9faaa651e | |||
1aca92b1c7 | |||
4444c58902 | |||
75dbae7cc6 | |||
79e0ac2a38 | |||
1cb4b191bf | |||
485392e772 | |||
9c5f6448b1 | |||
b78e52c5d4 | |||
e687f26d2d | |||
769808ca4e | |||
5ba20aec09 | |||
5c0efda0ca | |||
b6d3eb8ec2 | |||
30df948d81 | |||
15430af1d6 | |||
2aae298d7d | |||
adeaeb624b | |||
d98e235dfc | |||
ef5de018b0 | |||
c024340af7 | |||
6a964938bc | |||
f024a960e4 | |||
c3ff13856b | |||
806e1cc14f | |||
a48cdf6690 | |||
df646488d6 | |||
1a36e233be | |||
b8c5d613bc | |||
60455ae036 | |||
893db4034d | |||
3d1d4be997 | |||
5f3bd590a8 | |||
cbffc3f44b | |||
8131162dae | |||
72655aec3d | |||
08ed4075c7 | |||
6d5ddf1f8d | |||
8b354ff40e | |||
5be3d0b1a7 | |||
f0c4ea6bd0 | |||
cbe06426bb | |||
adac7395cc | |||
2c459a03d4 | |||
751bc450b5 | |||
6c8d9097f6 | |||
b0814d50dc | |||
a7a2424d93 | |||
43b15987d6 | |||
e100a580ad | |||
397bdee655 | |||
78b2d87ec1 | |||
8dedb39a33 | |||
7cee16389f | |||
04b2877c48 | |||
f6c7e5f954 | |||
b5ea22021b | |||
3ee1398e2f | |||
cfb07b81d5 | |||
0da23149db | |||
1322cb4eb0 | |||
167ad06dde | |||
271ee347a8 | |||
04a6d86999 | |||
05e6ff8f9b | |||
6e53ca8766 | |||
dda93cf3d3 | |||
075e4afa1c | |||
fd144d55f0 | |||
b595120227 | |||
b0b3b34bde | |||
2f592e2818 | |||
8c9bc40a02 | |||
37f77b3d50 | |||
a5130e1d9f | |||
256da35d53 | |||
bb93b1b313 | |||
195ed682f6 | |||
ae71b9649d | |||
71418548e7 | |||
03c7e0a7fa | |||
6bc8636692 | |||
c0d14596a7 | |||
6a72676c7c | |||
44c4997436 | |||
cce73886a2 | |||
b9733d7391 | |||
56ff0580a1 | |||
5b9f86fb38 | |||
d43a78d307 | |||
deedb002e8 | |||
6d7c2f725d | |||
5ede9b71c2 | |||
04f4c7be6d | |||
0c94b2f546 | |||
8b72ae01dc | |||
1ca77b89ce | |||
0934bf847d | |||
2a152a9a1d | |||
bc8fbc17b8 | |||
a8635f0c8a | |||
ca875f9f05 | |||
b4258fe496 | |||
509c95a680 | |||
2027c5918f | |||
3593e853d8 | |||
cb13d2b0c9 | |||
0f55df8d31 | |||
939cb8d53f | |||
730e4ac9c4 | |||
d3d96f795a | |||
e68f58fad1 | |||
6c0f34ae71 | |||
9373880239 | |||
a35036e0fa | |||
19246a59c9 | |||
15c4d1edd3 | |||
24f679d531 | |||
56f8f03581 | |||
ae1f15e8b8 | |||
7544bb9862 | |||
ebd078848a | |||
e8e4f98be0 | |||
c8c74d9be3 | |||
63541cf83a | |||
1cb54d46b1 | |||
cf3936b7c0 | |||
84df59c52b | |||
c75b71f217 | |||
269abc5699 | |||
638ddadb61 | |||
10f8340e76 | |||
7c0feae8ee | |||
25889b0759 | |||
1e0cca8685 | |||
a02a796f4a | |||
e640aa327e | |||
ed34728f5e | |||
b6e4b39e78 | |||
64f19f0f96 | |||
b6fb2d75b4 | |||
7138c07a89 | |||
137c151e19 | |||
548daad047 | |||
c8abde012c | |||
caa348a571 | |||
8e1488b86f | |||
1d4f8405b1 | |||
0fece8c7ca | |||
0deec384bc | |||
7452faab55 | |||
e9ed55b065 | |||
d35010f100 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ site/i18n/*.json
|
|||||||
core/vendor/tinymce/link_list.json
|
core/vendor/tinymce/link_list.json
|
||||||
robots.txt
|
robots.txt
|
||||||
sitemap.xml
|
sitemap.xml
|
||||||
|
core/module/config/tool/data.key
|
@ -32,5 +32,13 @@ Options -Indexes
|
|||||||
Options -MultiViews
|
Options -MultiViews
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
|
# Enlever le slash final des URL
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_URI} ^(.+)/$
|
||||||
|
RewriteRule ^ %1 [R=301,L]
|
||||||
|
|
||||||
# ne pas supprimer la ligne URL rewriting !
|
# ne pas supprimer la ligne URL rewriting !
|
||||||
|
|
||||||
# URL rewriting
|
# URL rewriting
|
||||||
|
|
||||||
|
15
README.md
15
README.md
@ -1,7 +1,17 @@
|
|||||||
# ZwiiCampus 1.7.04
|
# ZwiiCampus 1.14.07
|
||||||
|
|
||||||
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é.
|
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é.
|
||||||
|
|
||||||
|
Ce logiciel s'installe en ligne ou localement depuis un serveur Web.
|
||||||
|
|
||||||
|
## Principales fonctionnalités :
|
||||||
|
- Gestion des espaces d'enseignement : Créez des espaces de formation avec accès restreint.
|
||||||
|
- Participation et suivi des apprenants : Inscription libre, imposée ou avec clé, et suivi statistique détaillé des participants.
|
||||||
|
- Gestion des accès : Contrôlez la disponibilité des espaces (ouvert, limité dans le temps, fermé).
|
||||||
|
- Outils statistiques : Visualisation et exportation CSV des progrès des apprenants.
|
||||||
|
- Facilité d'installation : Pas besoin de base de données, tout fonctionne avec des fichiers JSON.
|
||||||
|
- Sauvegarde et restauration : Outils de gestion pour réinitialiser les espaces et les participations.
|
||||||
|
|
||||||
|
|
||||||
## Configuration recommandée
|
## Configuration recommandée
|
||||||
|
|
||||||
@ -68,6 +78,7 @@ A l'occasion de l'installation d'une version majeure, il est recommandé de réa
|
|||||||
[F] module.json Données des modules de pages
|
[F] module.json Données des modules de pages
|
||||||
[F] theme.css Thème de ce contenu
|
[F] theme.css Thème de ce contenu
|
||||||
[F] theme.json Thème de ce contenu
|
[F] theme.json Thème de ce contenu
|
||||||
|
[F] report.csv Rapport de participation
|
||||||
[R] content Dossier des contenus de page
|
[R] content Dossier des contenus de page
|
||||||
[F] accueil.html Exemple contenu de la page d'accueil
|
[F] accueil.html Exemple contenu de la page d'accueil
|
||||||
[R] fonts Dossier contenant les fontes installées
|
[R] fonts Dossier contenant les fontes installées
|
||||||
@ -84,7 +95,7 @@ A l'occasion de l'installation d'une version majeure, il est recommandé de réa
|
|||||||
[F] core.json Configuration du noyau
|
[F] core.json Configuration du noyau
|
||||||
[F] course.json Données de contenus
|
[F] course.json Données de contenus
|
||||||
[F] custom.css Feuille de style de la personnalisation avancée
|
[F] custom.css Feuille de style de la personnalisation avancée
|
||||||
[F] enrolment.json Données des inscriptions et des statistiques par contenu
|
[F] enrolment.json Inscriptions dans les espaces, dernière page vue et timetamp
|
||||||
[F] font.json Descripteur des fontes personnalisées
|
[F] font.json Descripteur des fontes personnalisées
|
||||||
[F] journal.log Journalisation des activités
|
[F] journal.log Journalisation des activités
|
||||||
[F] language.json Langues de l'interface
|
[F] language.json Langues de l'interface
|
||||||
|
@ -8,7 +8,7 @@ class helper
|
|||||||
|
|
||||||
/** Filtres personnalisés */
|
/** Filtres personnalisés */
|
||||||
const FILTER_BOOLEAN = 1;
|
const FILTER_BOOLEAN = 1;
|
||||||
const FILTER_DATETIME = 2;
|
const FILTER_DATETIME = 2; // filtre pour le champ de formulaire A conserver pour la compatibilité
|
||||||
const FILTER_FLOAT = 3;
|
const FILTER_FLOAT = 3;
|
||||||
const FILTER_ID = 4;
|
const FILTER_ID = 4;
|
||||||
const FILTER_INT = 5;
|
const FILTER_INT = 5;
|
||||||
@ -16,8 +16,14 @@ class helper
|
|||||||
const FILTER_PASSWORD = 7;
|
const FILTER_PASSWORD = 7;
|
||||||
const FILTER_STRING_LONG = 8;
|
const FILTER_STRING_LONG = 8;
|
||||||
const FILTER_STRING_SHORT = 9;
|
const FILTER_STRING_SHORT = 9;
|
||||||
const FILTER_TIMESTAMP = 10;
|
const FILTER_TIMESTAMP = 10; // Saisie d'une date en locatime
|
||||||
const FILTER_URL = 11;
|
const FILTER_URL = 11;
|
||||||
|
const FILTER_DATE = 12; // filtre pour le champ de formulaire
|
||||||
|
const FILTER_TIME = 13; // filtre pour le champ de formulair
|
||||||
|
const FILTER_MONTH = 14; // filtre pour le champ de formulair
|
||||||
|
const FILTER_YEAR = 16; // filtre pour le champ de formulair
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,12 +35,12 @@ class helper
|
|||||||
|
|
||||||
// La traduction existe déjà dans le core
|
// La traduction existe déjà dans le core
|
||||||
/*
|
/*
|
||||||
if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
|
if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
|
||||||
$dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true);
|
$dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true);
|
||||||
$data = array_merge($dialogues,[$text => '']);
|
$data = array_merge($dialogues,[$text => '']);
|
||||||
file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
|
file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text);
|
return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +83,7 @@ class helper
|
|||||||
// Créer la variable
|
// Créer la variable
|
||||||
$data = array_merge($data, [$text => '']);
|
$data = array_merge($data, [$text => '']);
|
||||||
}
|
}
|
||||||
file_put_contents('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
|
file_put_contents('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,17 +343,24 @@ class helper
|
|||||||
public static function checkRewrite()
|
public static function checkRewrite()
|
||||||
{
|
{
|
||||||
// N'interroge que le serveur Apache
|
// N'interroge que le serveur Apache
|
||||||
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) {
|
if ((helper::checkServerSoftware() === false)) {
|
||||||
self::$rewriteStatus === false;
|
self::$rewriteStatus = false;
|
||||||
} elseif (self::$rewriteStatus === null) {
|
} else {
|
||||||
// Ouvre et scinde le fichier .htaccess
|
// Ouvre et scinde le fichier .htaccess
|
||||||
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
|
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
|
||||||
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
|
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
|
||||||
//self::$rewriteStatus = (empty($htaccess[1]) === false);
|
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') !== false);
|
||||||
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') > 0) ? true : false;
|
|
||||||
}
|
}
|
||||||
return self::$rewriteStatus;
|
return self::$rewriteStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne vrai ou faux selon que le serveur est comptatible avec htaccess
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function checkServerSoftware() {
|
||||||
|
return (stripos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false || stripos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie le numéro de version de Zwii est en ligne
|
* Renvoie le numéro de version de Zwii est en ligne
|
||||||
@ -368,11 +381,10 @@ class helper
|
|||||||
$version = helper::getOnlineVersion($channel);
|
$version = helper::getOnlineVersion($channel);
|
||||||
$update = false;
|
$update = false;
|
||||||
if (!empty($version)) {
|
if (!empty($version)) {
|
||||||
$update = version_compare(common::ZWII_VERSION, $version) == -1;
|
$update = version_compare(common::ZWII_VERSION, $version) == -1;
|
||||||
}
|
}
|
||||||
return $update;
|
return $update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,10 +403,10 @@ class helper
|
|||||||
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
|
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
|
||||||
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')',
|
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')',
|
||||||
'invert' => 'rgba (' .
|
'invert' => 'rgba (' .
|
||||||
($rgba[0] < 128 ? 255 : 0) . ',' .
|
($rgba[0] < 128 ? 255 : 0) . ',' .
|
||||||
($rgba[1] < 128 ? 255 : 0) . ',' .
|
($rgba[1] < 128 ? 255 : 0) . ',' .
|
||||||
($rgba[1] < 128 ? 255 : 0) . ',' .
|
($rgba[1] < 128 ? 255 : 0) . ',' .
|
||||||
($rgba[0] < 128 ? 255 : 0) . ')'
|
($rgba[0] < 128 ? 255 : 0) . ')'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,8 +416,8 @@ class helper
|
|||||||
*/
|
*/
|
||||||
public static function deleteCookie($cookieKey)
|
public static function deleteCookie($cookieKey)
|
||||||
{
|
{
|
||||||
unset($_COOKIE[$cookieKey]);
|
|
||||||
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
|
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
|
||||||
|
unset($_COOKIE[$cookieKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,7 +440,8 @@ class helper
|
|||||||
$text = (int) $date->format('U');
|
$text = (int) $date->format('U');
|
||||||
break;
|
break;
|
||||||
case self::FILTER_FLOAT:
|
case self::FILTER_FLOAT:
|
||||||
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT);
|
$text = str_replace(',', '.', $text); // Remplacer les virgules par des points
|
||||||
|
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
|
||||||
$text = (float) $text;
|
$text = (float) $text;
|
||||||
break;
|
break;
|
||||||
case self::FILTER_ID:
|
case self::FILTER_ID:
|
||||||
@ -475,6 +488,11 @@ class helper
|
|||||||
case self::FILTER_URL:
|
case self::FILTER_URL:
|
||||||
$text = filter_var($text, FILTER_SANITIZE_URL);
|
$text = filter_var($text, FILTER_SANITIZE_URL);
|
||||||
break;
|
break;
|
||||||
|
case self::FILTER_DATE:
|
||||||
|
$text = date('Y-m-d', $text);
|
||||||
|
break;
|
||||||
|
case self::FILTER_TIME:
|
||||||
|
$text = date('H:i', $text);
|
||||||
}
|
}
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
@ -663,10 +681,30 @@ class helper
|
|||||||
public static function subword($text, $start, $length)
|
public static function subword($text, $start, $length)
|
||||||
{
|
{
|
||||||
$text = trim($text);
|
$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, $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;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,10 +121,10 @@ class JsonDb extends \Prowebcraft\Dot
|
|||||||
} else {
|
} else {
|
||||||
if ($this->config['backup']) {
|
if ($this->config['backup']) {
|
||||||
try {
|
try {
|
||||||
//todo make backup of database
|
|
||||||
copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
|
copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
error_log('Erreur de chargement : ' . $e);
|
||||||
|
exit('Erreur de chargement : ' . $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,25 +142,38 @@ class JsonDb extends \Prowebcraft\Dot
|
|||||||
*/
|
*/
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
$v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
|
// Encode les données au format JSON avec les options spécifiées
|
||||||
// $v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
|
$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
|
||||||
$l = strlen($v);
|
|
||||||
$t = 0;
|
// Vérifie la longueur de la chaîne JSON encodée
|
||||||
if ($v === false) {
|
$encoded_length = strlen($encoded_data);
|
||||||
error_log('Erreur d\'encodage JSON : ' . json_last_error_msg());
|
|
||||||
exit ('Erreur d\'encodage JSON : ' . json_last_error_msg());
|
// Initialise le compteur de tentatives
|
||||||
}
|
$attempt = 0;
|
||||||
while ($t < 5) {
|
|
||||||
$w = file_put_contents($this->db, $v); // Multi user get a locker
|
// Tente d'encoder les données en JSON et de les sauvegarder jusqu'à 5 fois en cas d'échec
|
||||||
if ($w == $l) {
|
while ($attempt < 5) {
|
||||||
|
// Essaye d'écrire les données encodées dans le fichier de base de données
|
||||||
|
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
|
||||||
|
|
||||||
|
// $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;
|
break;
|
||||||
}
|
}
|
||||||
$t++;
|
// Incrémente le compteur de tentatives
|
||||||
|
$attempt++;
|
||||||
}
|
}
|
||||||
if ($w !== $l) {
|
// Vérifie si l'écriture a échoué même après plusieurs tentatives
|
||||||
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
if ($write_result !== $encoded_length) {
|
||||||
|
// Enregistre un message d'erreur dans le journal des erreurs
|
||||||
|
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
||||||
|
// Affiche un message d'erreur et termine le script
|
||||||
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -82,17 +82,25 @@ class layout extends common
|
|||||||
$content = 'col' . $blocks[1];
|
$content = 'col' . $blocks[1];
|
||||||
$blockright = 'col' . $blocks[2];
|
$blockright = 'col' . $blocks[2];
|
||||||
}
|
}
|
||||||
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
|
// 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'];
|
$pattern = ['config', 'edit', 'add', 'comment', 'data', 'option', 'theme', 'comment', 'article', 'data', 'gallery', 'update', 'users', 'validate'];
|
||||||
if (
|
if (
|
||||||
(sizeof($blocks) === 1 ||
|
(sizeof($blocks) === 1 ||
|
||||||
in_array($this->getUrl(1), $pattern))
|
in_array($this->getUrl(1), $pattern))
|
||||||
) { // Pleine page en mode configuration
|
) { // Pleine page en mode configuration
|
||||||
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top') {
|
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->showNavButtons('top');
|
||||||
}
|
}
|
||||||
$this->showContent();
|
$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');
|
$this->showNavButtons('bottom');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -151,7 +159,7 @@ class layout extends common
|
|||||||
}
|
}
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
}
|
}
|
||||||
echo '</main></section>';
|
echo '</section></main>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -330,7 +338,7 @@ class layout extends common
|
|||||||
// Affichage du lien de connexion
|
// Affichage du lien de connexion
|
||||||
if (
|
if (
|
||||||
($this->getData(['theme', 'footer', 'loginLink'])
|
($this->getData(['theme', 'footer', 'loginLink'])
|
||||||
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
|
and $this->isConnected() === false
|
||||||
)
|
)
|
||||||
or $this->getUrl(0) === 'theme'
|
or $this->getUrl(0) === 'theme'
|
||||||
) {
|
) {
|
||||||
@ -352,11 +360,11 @@ class layout extends common
|
|||||||
$items .= $this->getData(['theme', 'footer', 'displaymemberAccount']) === false ? ' class="displayNone">' : '>';
|
$items .= $this->getData(['theme', 'footer', 'displaymemberAccount']) === false ? ' class="displayNone">' : '>';
|
||||||
$items .= '<wbr> | ';
|
$items .= '<wbr> | ';
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', 'filemanager') === true
|
$this->getUser('permission', 'filemanager') === true
|
||||||
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none'
|
&& $this->getUser('permission', 'folder', (self::$siteContent === 'home' ? 'homePath' : 'coursePath')) !== 'none'
|
||||||
) {
|
) {
|
||||||
$items .= '<wbr>' . template::ico('folder', [
|
$items .= '<wbr>' . template::ico('folder', [
|
||||||
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&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',
|
'margin' => 'all',
|
||||||
'attr' => 'data-lity',
|
'attr' => 'data-lity',
|
||||||
'help' => 'Fichiers du site'
|
'help' => 'Fichiers du site'
|
||||||
@ -520,8 +528,10 @@ class layout extends common
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
// Affiche l'icône RFM
|
// Affiche l'icône RFM
|
||||||
if ($this->getUser('permission', 'filemanager') === true
|
if (
|
||||||
&& $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'
|
||||||
|
) {
|
||||||
$itemsRight .= '<li>' . template::ico('folder', [
|
$itemsRight .= '<li>' . template::ico('folder', [
|
||||||
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&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',
|
'attr' => 'data-lity',
|
||||||
@ -547,7 +557,7 @@ class layout extends common
|
|||||||
// Lien de connexion
|
// Lien de connexion
|
||||||
if (
|
if (
|
||||||
($this->getData(['theme', 'menu', 'loginLink'])
|
($this->getData(['theme', 'menu', 'loginLink'])
|
||||||
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
|
and $this->isConnected() === false
|
||||||
)
|
)
|
||||||
or $this->getUrl(0) === 'theme'
|
or $this->getUrl(0) === 'theme'
|
||||||
) {
|
) {
|
||||||
@ -592,9 +602,9 @@ class layout extends common
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
($this->getData(['page', $parentPageId, 'disable']) === true
|
($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
|
) 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
|
and $this->getUser('group') < self::GROUP_EDITOR
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -658,9 +668,9 @@ class layout extends common
|
|||||||
$items .= '<li id=' . $childKey . '>';
|
$items .= '<li id=' . $childKey . '>';
|
||||||
if (
|
if (
|
||||||
($this->getData(['page', $childKey, 'disable']) === true
|
($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
|
) 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
|
and $this->getUser('group') < self::GROUP_EDITOR
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -754,7 +764,7 @@ class layout extends common
|
|||||||
$items .= '<li class="menuSideChild">';
|
$items .= '<li class="menuSideChild">';
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $parentPageId, 'disable']) === true
|
$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) . '">';
|
$items .= '<a href="' . $this->getUrl(1) . '">';
|
||||||
} else {
|
} else {
|
||||||
@ -778,7 +788,7 @@ class layout extends common
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $childKey, 'disable']) === true
|
$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) . '">';
|
$itemsChildren .= '<a href="' . $this->getUrl(1) . '">';
|
||||||
} else {
|
} else {
|
||||||
@ -914,7 +924,7 @@ class layout extends common
|
|||||||
*/
|
*/
|
||||||
public function showBar()
|
public function showBar()
|
||||||
{
|
{
|
||||||
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
|
if ($this->isConnected() === true) {
|
||||||
// Items de gauche
|
// Items de gauche
|
||||||
$leftItems = '';
|
$leftItems = '';
|
||||||
// Sélecteur de contenu
|
// Sélecteur de contenu
|
||||||
@ -931,7 +941,7 @@ class layout extends common
|
|||||||
}
|
}
|
||||||
$leftItems .= '</select></li>';
|
$leftItems .= '</select></li>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$leftItems .= '<li>' . template::ico('cubes', [
|
$leftItems .= '<li>' . template::ico('cubes', [
|
||||||
'href' => helper::baseUrl() . 'course',
|
'href' => helper::baseUrl() . 'course',
|
||||||
'help' => 'Gérer les espaces'
|
'help' => 'Gérer les espaces'
|
||||||
@ -1001,7 +1011,7 @@ class layout extends common
|
|||||||
// Bouton Ajouter une page
|
// Bouton Ajouter une page
|
||||||
if ($this->getUser('permission', 'page', 'add')) {
|
if ($this->getUser('permission', 'page', 'add')) {
|
||||||
$leftItems .= '<li>' . template::ico('plus', [
|
$leftItems .= '<li>' . template::ico('plus', [
|
||||||
'href' => helper::baseUrl() . 'page/add',
|
'href' => helper::baseUrl() . 'page/add/' . self::$siteContent,
|
||||||
'help' => 'Nouvelle page ou barre latérale'
|
'help' => 'Nouvelle page ou barre latérale'
|
||||||
]) . '</li>';
|
]) . '</li>';
|
||||||
}
|
}
|
||||||
@ -1018,16 +1028,20 @@ class layout extends common
|
|||||||
or $this->getUrl(0) === ''
|
or $this->getUrl(0) === ''
|
||||||
) {
|
) {
|
||||||
// Bouton Editer une page
|
// Bouton Editer une page
|
||||||
if ($this->getUser('permission', 'page', 'edit')) {
|
if (
|
||||||
|
$this->getUser('permission', 'page', 'edit')
|
||||||
|
and $this->geturl(1) !== 'edit'
|
||||||
|
) {
|
||||||
$leftItems .= '<li>' . template::ico('pencil', [
|
$leftItems .= '<li>' . template::ico('pencil', [
|
||||||
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
|
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
|
||||||
'help' => 'Éditer la page'
|
'help' => 'Éditer la page'
|
||||||
]) . '</li>';
|
]) . '</li>';
|
||||||
}
|
}
|
||||||
// Bouton Editer le module d'une page
|
// Bouton Editer le module d'une page
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', 'page', 'module')
|
$this->getUser('permission', 'page', 'module')
|
||||||
&& $this->getData(['page', $this->getUrl(0), 'moduleId'])
|
and $this->geturl(1) !== 'edit'
|
||||||
|
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
|
||||||
) {
|
) {
|
||||||
$leftItems .= '<li>' . template::ico('gear', [
|
$leftItems .= '<li>' . template::ico('gear', [
|
||||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
|
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
|
||||||
@ -1037,9 +1051,10 @@ class layout extends common
|
|||||||
// Bouton dupliquer une page
|
// Bouton dupliquer une page
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', 'page', 'duplicate')
|
$this->getUser('permission', 'page', 'duplicate')
|
||||||
|
and $this->geturl(1) !== 'edit'
|
||||||
) {
|
) {
|
||||||
$leftItems .= '<li>' . template::ico('clone', [
|
$leftItems .= '<li>' . template::ico('clone', [
|
||||||
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0),
|
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
|
||||||
'help' => 'Dupliquer la page'
|
'help' => 'Dupliquer la page'
|
||||||
])
|
])
|
||||||
. '</li>';
|
. '</li>';
|
||||||
@ -1047,9 +1062,11 @@ class layout extends common
|
|||||||
// Bouton Effacer une page
|
// Bouton Effacer une page
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', 'page', 'delete')
|
$this->getUser('permission', 'page', 'delete')
|
||||||
|
and $this->geturl(1) !== 'edit'
|
||||||
|
|
||||||
) {
|
) {
|
||||||
$leftItems .= '<li>' . template::ico('trash', [
|
$leftItems .= '<li>' . template::ico('trash', [
|
||||||
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0),
|
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
|
||||||
'help' => 'Supprimer la page',
|
'help' => 'Supprimer la page',
|
||||||
'id' => 'pageDelete'
|
'id' => 'pageDelete'
|
||||||
])
|
])
|
||||||
@ -1069,7 +1086,7 @@ class layout extends common
|
|||||||
) {
|
) {
|
||||||
$rightItems .= '<li>' . template::ico('folder', [
|
$rightItems .= '<li>' . template::ico('folder', [
|
||||||
'help' => 'Fichiers',
|
'help' => 'Fichiers',
|
||||||
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']) . '&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'
|
'attr' => 'data-lity'
|
||||||
]) . '</li>';
|
]) . '</li>';
|
||||||
}
|
}
|
||||||
@ -1077,22 +1094,18 @@ class layout extends common
|
|||||||
self::$siteContent === 'home'
|
self::$siteContent === 'home'
|
||||||
&& $this->getUser('group') >= self::GROUP_ADMIN
|
&& $this->getUser('group') >= self::GROUP_ADMIN
|
||||||
) {
|
) {
|
||||||
$rightItems .= '<li>' . template::ico('puzzle', [
|
|
||||||
'help' => 'Modules',
|
|
||||||
'href' => helper::baseUrl() . 'plugin'
|
|
||||||
]) . '</li>';
|
|
||||||
$rightItems .= '<li>' . template::ico('flag', [
|
$rightItems .= '<li>' . template::ico('flag', [
|
||||||
'help' => 'Langues',
|
'help' => 'Langues',
|
||||||
'href' => helper::baseUrl() . 'language'
|
'href' => helper::baseUrl() . 'language'
|
||||||
]) . '</li>';
|
]) . '</li>';
|
||||||
$rightItems .= '<li>' . template::ico('cog-alt', [
|
|
||||||
'help' => 'Configuration',
|
|
||||||
'href' => helper::baseUrl() . 'config'
|
|
||||||
]) . '</li>';
|
|
||||||
$rightItems .= '<li>' . template::ico('users', [
|
$rightItems .= '<li>' . template::ico('users', [
|
||||||
'help' => 'Utilisateurs',
|
'help' => 'Utilisateurs',
|
||||||
'href' => helper::baseUrl() . 'user'
|
'href' => helper::baseUrl() . 'user'
|
||||||
]) . '</li>';
|
]) . '</li>';
|
||||||
|
$rightItems .= '<li>' . template::ico('cog-alt', [
|
||||||
|
'help' => 'Configuration',
|
||||||
|
'href' => helper::baseUrl() . 'config'
|
||||||
|
]) . '</li>';
|
||||||
// Mise à jour automatique
|
// Mise à jour automatique
|
||||||
$today = mktime(0, 0, 0);
|
$today = mktime(0, 0, 0);
|
||||||
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
|
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
|
||||||
@ -1104,21 +1117,54 @@ class layout extends common
|
|||||||
$today > $checkUpdate + $this->getData(['config', 'autoUpdateDelay', 86400])
|
$today > $checkUpdate + $this->getData(['config', 'autoUpdateDelay', 86400])
|
||||||
) {
|
) {
|
||||||
// Dernier auto controle
|
// Dernier auto controle
|
||||||
$this->setData(['core', 'lastAutoUpdate', $today]);
|
$this->setData(['core', 'lastAutoUpdate', $today], false);
|
||||||
if (
|
if (
|
||||||
helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)
|
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
|
// Afficher le bouton : Mise à jour détectée + activée
|
||||||
if ($this->getData(['core', 'updateAvailable'])) {
|
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>';
|
$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 (
|
if (
|
||||||
$this->getUser('group') >= self::GROUP_EDITOR
|
$this->getUser('group') >= self::GROUP_EDITOR
|
||||||
&& $this->getUser('permission', 'user', 'edit')
|
&& $this->getUser('permission', 'user', 'edit')
|
||||||
@ -1206,7 +1252,7 @@ class layout extends common
|
|||||||
$vars = 'var baseUrl = ' . json_encode(helper::baseUrl(false)) . ';';
|
$vars = 'var baseUrl = ' . json_encode(helper::baseUrl(false)) . ';';
|
||||||
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
|
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
|
||||||
if (
|
if (
|
||||||
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
$this->isConnected() === true
|
||||||
and $this->getUser('group') >= self::GROUP_EDITOR
|
and $this->getUser('group') >= self::GROUP_EDITOR
|
||||||
) {
|
) {
|
||||||
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';
|
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';
|
||||||
|
@ -11,16 +11,16 @@ class core extends common
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
// Token CSRF
|
// Token CSRF
|
||||||
if (empty($_SESSION['csrf'])) {
|
if (empty($_SESSION['csrf'])) {
|
||||||
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128));
|
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fuseau horaire
|
// Fuseau horaire
|
||||||
self::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
|
common::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
|
||||||
date_default_timezone_set(self::$timezone);
|
date_default_timezone_set(common::$timezone);
|
||||||
// Supprime les fichiers temporaires
|
// Supprime les fichiers temporaires
|
||||||
$lastClearTmp = mktime(0, 0, 0);
|
$lastClearTmp = mktime(0, 0, 0);
|
||||||
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
|
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
|
||||||
$iterator = new DirectoryIterator(self::TEMP_DIR);
|
$iterator = new DirectoryIterator(common::TEMP_DIR);
|
||||||
foreach ($iterator as $fileInfos) {
|
foreach ($iterator as $fileInfos) {
|
||||||
if (
|
if (
|
||||||
$fileInfos->isFile() &&
|
$fileInfos->isFile() &&
|
||||||
@ -32,8 +32,6 @@ class core extends common
|
|||||||
}
|
}
|
||||||
// Date de la dernière suppression
|
// Date de la dernière suppression
|
||||||
$this->setData(['core', 'lastClearTmp', $lastClearTmp]);
|
$this->setData(['core', 'lastClearTmp', $lastClearTmp]);
|
||||||
// Enregistre les données
|
|
||||||
//$this->SaveData();
|
|
||||||
}
|
}
|
||||||
// Backup automatique des données
|
// Backup automatique des données
|
||||||
$lastBackup = mktime(0, 0, 0);
|
$lastBackup = mktime(0, 0, 0);
|
||||||
@ -43,11 +41,11 @@ class core extends common
|
|||||||
and $this->getData(['user']) // Pas de backup pendant l'installation
|
and $this->getData(['user']) // Pas de backup pendant l'installation
|
||||||
) {
|
) {
|
||||||
// Copie des fichier de données
|
// Copie des fichier de données
|
||||||
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
|
helper::autoBackup(common::BACKUP_DIR, ['backup', 'tmp', 'file']);
|
||||||
// Date du dernier backup
|
// Date du dernier backup
|
||||||
$this->setData(['core', 'lastBackup', $lastBackup]);
|
$this->setData(['core', 'lastBackup', $lastBackup]);
|
||||||
// Supprime les backups de plus de 30 jours
|
// Supprime les backups de plus de 30 jours
|
||||||
$iterator = new DirectoryIterator(self::BACKUP_DIR);
|
$iterator = new DirectoryIterator(common::BACKUP_DIR);
|
||||||
foreach ($iterator as $fileInfos) {
|
foreach ($iterator as $fileInfos) {
|
||||||
if (
|
if (
|
||||||
$fileInfos->isFile()
|
$fileInfos->isFile()
|
||||||
@ -60,23 +58,23 @@ class core extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crée le fichier de personnalisation avancée
|
// Crée le fichier de personnalisation avancée
|
||||||
if (file_exists(self::DATA_DIR . 'custom.css') === false) {
|
if (file_exists(common::DATA_DIR . 'custom.css') === false) {
|
||||||
file_put_contents(self::DATA_DIR . 'custom.css', ('core/module/theme/resource/custom.css'));
|
file_put_contents(common::DATA_DIR . 'custom.css', ('core/module/theme/resource/custom.css'));
|
||||||
chmod(self::DATA_DIR . 'custom.css', 0755);
|
chmod(common::DATA_DIR . 'custom.css', 0755);
|
||||||
}
|
}
|
||||||
// Crée le fichier de personnalisation
|
// Crée le fichier de personnalisation
|
||||||
if (file_exists(self::DATA_DIR . self::$siteContent . '/theme.css') === false) {
|
if (file_exists(common::DATA_DIR . common::$siteContent . '/theme.css') === false) {
|
||||||
file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', '');
|
file_put_contents(common::DATA_DIR . common::$siteContent . '/theme.css', '');
|
||||||
chmod(self::DATA_DIR . self::$siteContent . '/theme.css', 0755);
|
chmod(common::DATA_DIR . common::$siteContent . '/theme.css', 0755);
|
||||||
}
|
}
|
||||||
// Crée le fichier de personnalisation de l'administration
|
// Crée le fichier de personnalisation de l'administration
|
||||||
if (file_exists(self::DATA_DIR . 'admin.css') === false) {
|
if (file_exists(common::DATA_DIR . 'admin.css') === false) {
|
||||||
file_put_contents(self::DATA_DIR . 'admin.css', '');
|
file_put_contents(common::DATA_DIR . 'admin.css', '');
|
||||||
chmod(self::DATA_DIR . 'admin.css', 0755);
|
chmod(common::DATA_DIR . 'admin.css', 0755);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check la version rafraichissement du theme
|
// Check la version rafraichissement du theme
|
||||||
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . self::$siteContent . '/theme.css'));
|
$cssVersion = preg_split('/\*+/', file_get_contents(common::DATA_DIR . common::$siteContent . '/theme.css'));
|
||||||
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
|
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
|
||||||
// Version
|
// Version
|
||||||
$css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/';
|
$css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/';
|
||||||
@ -92,7 +90,7 @@ class core extends common
|
|||||||
// Fonts disponibles
|
// Fonts disponibles
|
||||||
$fontsAvailable['files'] = $this->getData(['font', 'files']);
|
$fontsAvailable['files'] = $this->getData(['font', 'files']);
|
||||||
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
|
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
|
||||||
$fontsAvailable['websafe'] = self::$fontsWebSafe;
|
$fontsAvailable['websafe'] = common::$fontsWebSafe;
|
||||||
|
|
||||||
// Fontes installées
|
// Fontes installées
|
||||||
$fonts = [
|
$fonts = [
|
||||||
@ -273,7 +271,7 @@ class core extends common
|
|||||||
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
|
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
|
||||||
|
|
||||||
// Enregistre la personnalisation
|
// Enregistre la personnalisation
|
||||||
file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', $css);
|
file_put_contents(common::DATA_DIR . common::$siteContent . '/theme.css', $css);
|
||||||
|
|
||||||
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
|
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
|
||||||
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
|
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
|
||||||
@ -284,7 +282,7 @@ class core extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check la version rafraichissement du theme admin
|
// Check la version rafraichissement du theme admin
|
||||||
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'admin.css'));
|
$cssVersion = preg_split('/\*+/', file_get_contents(common::DATA_DIR . 'admin.css'));
|
||||||
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
|
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
@ -293,7 +291,7 @@ class core extends common
|
|||||||
// Fonts disponibles
|
// Fonts disponibles
|
||||||
$fontsAvailable['files'] = $this->getData(['font', 'files']);
|
$fontsAvailable['files'] = $this->getData(['font', 'files']);
|
||||||
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
|
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
|
||||||
$fontsAvailable['websafe'] = self::$fontsWebSafe;
|
$fontsAvailable['websafe'] = common::$fontsWebSafe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import des polices de caractères
|
* Import des polices de caractères
|
||||||
@ -368,7 +366,7 @@ class core extends common
|
|||||||
// Bordure du contour TinyMCE
|
// Bordure du contour TinyMCE
|
||||||
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
|
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
|
||||||
// Enregistre la personnalisation
|
// Enregistre la personnalisation
|
||||||
file_put_contents(self::DATA_DIR . 'admin.css', $css);
|
file_put_contents(common::DATA_DIR . 'admin.css', $css);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -384,8 +382,8 @@ class core extends common
|
|||||||
require 'core/module/' . $classPath;
|
require 'core/module/' . $classPath;
|
||||||
}
|
}
|
||||||
// Module
|
// Module
|
||||||
elseif (is_readable(self::MODULE_DIR . $classPath)) {
|
elseif (is_readable(common::MODULE_DIR . $classPath)) {
|
||||||
require self::MODULE_DIR . $classPath;
|
require common::MODULE_DIR . $classPath;
|
||||||
}
|
}
|
||||||
// Librairie
|
// Librairie
|
||||||
elseif (is_readable('core/vendor/' . $classPath)) {
|
elseif (is_readable('core/vendor/' . $classPath)) {
|
||||||
@ -414,22 +412,23 @@ class core extends common
|
|||||||
// Sauvegarde la dernière page visitée par l'utilisateur connecté et enregistre l'historique des consultations
|
// Sauvegarde la dernière page visitée par l'utilisateur connecté et enregistre l'historique des consultations
|
||||||
if (
|
if (
|
||||||
$this->getUser('id')
|
$this->getUser('id')
|
||||||
&& self::$siteContent !== 'home'
|
&& common::$siteContent !== 'home'
|
||||||
&& in_array($this->getUrl(0), array_keys($this->getData(['page'])))
|
&& in_array($this->getUrl(0), array_keys($this->getData(['page'])))
|
||||||
// Le userId n'est pas celui d'un admis ni le prof du contenu
|
// Le userId n'est pas celui d'un admis ni le prof du contenu
|
||||||
&& (
|
&& (
|
||||||
$this->getUser('group') < self::GROUP_ADMIN
|
$this->getUser('group') < common::GROUP_ADMIN
|
||||||
|| $this->getUser('id') !== $this->getData(['course', self::$siteContent, 'author'])
|
|| $this->getUser('id') !== $this->getData(['course', common::$siteContent, 'author'])
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// Stocke l'historique des pages vues
|
|
||||||
$data = is_array($this->getData(['enrolment', self::$siteContent, $this->getUser('id'), 'history', $this->getUrl(0)]))
|
|
||||||
? array_merge([time()], $this->getData(['enrolment', self::$siteContent, $this->getUser('id'), 'history', $this->getUrl(0)]))
|
|
||||||
: [time()];
|
|
||||||
$this->setData(['enrolment', self::$siteContent, $this->getUser('id'), 'history', $this->getUrl(0), $data]);
|
|
||||||
// Stocke la dernière page vue et sa date de consultation
|
// Stocke la dernière page vue et sa date de consultation
|
||||||
$this->setData(['enrolment', self::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)]);
|
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)], false);
|
||||||
$this->setData(['enrolment', self::$siteContent, $this->getUser('id'), 'datePageView', time()]);
|
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'datePageView', time()]);
|
||||||
|
|
||||||
|
// Stocke le rapport en CSV
|
||||||
|
$file = fopen(common::DATA_DIR . common::$siteContent . '/report.csv', 'a+');
|
||||||
|
fputcsv($file, [$this->getUser('id'), $this->getUrl(0), time()], ';');
|
||||||
|
fclose($file);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Journalisation
|
// Journalisation
|
||||||
@ -437,8 +436,8 @@ class core extends common
|
|||||||
|
|
||||||
// Force la déconnexion des membres bannis ou d'une seconde session
|
// Force la déconnexion des membres bannis ou d'une seconde session
|
||||||
if (
|
if (
|
||||||
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
$this->isConnected() === true
|
||||||
and ($this->getUser('group') === self::GROUP_BANNED
|
and ($this->getUser('group') === common::GROUP_BANNED
|
||||||
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
|
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
|
||||||
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
|
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
|
||||||
)
|
)
|
||||||
@ -451,9 +450,9 @@ class core extends common
|
|||||||
$this->getData(['config', 'maintenance'])
|
$this->getData(['config', 'maintenance'])
|
||||||
and in_array($this->getUrl(0), ['maintenance', 'user']) === false
|
and in_array($this->getUrl(0), ['maintenance', 'user']) === false
|
||||||
and $this->getUrl(1) !== 'login'
|
and $this->getUrl(1) !== 'login'
|
||||||
and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
|
and ($this->isConnected() === false
|
||||||
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
or ($this->isConnected() === true
|
||||||
and $this->getUser('group') < self::GROUP_ADMIN
|
and $this->getUser('group') < common::GROUP_ADMIN
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -466,32 +465,12 @@ class core extends common
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pour éviter une 404 sur une langue étrangère, bascule dans la langue correcte.
|
|
||||||
if (is_null($this->getData(['page', $this->getUrl(0)]))) {
|
|
||||||
foreach ($this->getData(['course']) as $key => $value) {;
|
|
||||||
if (
|
|
||||||
is_dir(self::DATA_DIR . $key) &&
|
|
||||||
file_exists(self::DATA_DIR . $key . '/page.json')
|
|
||||||
) {
|
|
||||||
$pagesId = json_decode(file_get_contents(self::DATA_DIR . $key . '/page.json'), true);
|
|
||||||
if (
|
|
||||||
is_array($pagesId['page']) &&
|
|
||||||
array_key_exists($this->getUrl(0), $pagesId['page'])
|
|
||||||
) {
|
|
||||||
//$_SESSION['ZWII_SITE_CONTENT'] = $key;
|
|
||||||
header('Refresh:0; url=' . helper::baseUrl() . 'course/swap/' . $key . '/' . $this->getUrl(0));
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check l'accès à la page
|
// Check l'accès à la page
|
||||||
$access = null;
|
$access = null;
|
||||||
if ($this->getData(['page', $this->getUrl(0)]) !== null) {
|
if ($this->getData(['page', $this->getUrl(0)]) !== null) {
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $this->getUrl(0), 'group']) === self::GROUP_VISITOR
|
$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'])
|
// and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group'])
|
||||||
// Modification qui tient compte du profil de la page
|
// 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']))
|
and ($this->getUser('group') * 10 + $this->getUser('profil')) >= ($this->getData(['page', $this->getUrl(0), 'group']) * 10 + $this->getData(['page', $this->getUrl(0), 'profil']))
|
||||||
@ -508,14 +487,54 @@ class core extends common
|
|||||||
// Empêcher l'accès aux pages désactivées par URL directe
|
// Empêcher l'accès aux pages désactivées par URL directe
|
||||||
if (
|
if (
|
||||||
($this->getData(['page', $this->getUrl(0), 'disable']) === true
|
($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
|
) 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') < self::GROUP_EDITOR
|
and $this->getUser('group') < common::GROUP_EDITOR
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$access = false;
|
$access = false;
|
||||||
}
|
}
|
||||||
|
// Lève une erreur si l'url est celle d'une page avec des éléments surnuméraires https://www.site.fr/page/truc
|
||||||
|
if (
|
||||||
|
array_key_exists($this->getUrl(0), $this->getData(['page']))
|
||||||
|
and $this->getUrl(1)
|
||||||
|
and $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
|
||||||
|
) {
|
||||||
|
$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();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Récupère les statistiques de l'utilisateur non admin
|
||||||
|
* en dehors de home
|
||||||
|
* et si la connextion est nécessaire et que le membre est connecté
|
||||||
|
* stocke la progression dans la base des inscriptions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
$this->isConnected() === true
|
||||||
|
and self::$siteContent !== 'home'
|
||||||
|
and $this->getData(['course', self::$siteContent, 'enrolment']) > 0
|
||||||
|
) {
|
||||||
|
$course = new course();
|
||||||
|
self::$userProgress = $course->userProgress(self::$siteContent, $this->getUser('id'));
|
||||||
|
$this->setData(['enrolment', self::$siteContent, $this->getUser('id'), 'progress', self::$userProgress ]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -537,9 +556,9 @@ class core extends common
|
|||||||
$this->getUser('id') &&
|
$this->getUser('id') &&
|
||||||
$userId !== $this->getUser('id') &&
|
$userId !== $this->getUser('id') &&
|
||||||
$this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() &&
|
$this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() &&
|
||||||
array_intersect($t, self::$concurrentAccess) &&
|
array_intersect($t, common::$concurrentAccess) &&
|
||||||
//array_intersect($t, self::$accessExclude) !== false &&
|
//array_intersect($t, common::$accessExclude) !== false &&
|
||||||
time() < $this->getData(['user', $userId, 'accessTimer']) + self::ACCESS_TIMER
|
time() < $this->getData(['user', $userId, 'accessTimer']) + common::ACCESS_TIMER
|
||||||
) {
|
) {
|
||||||
$access = false;
|
$access = false;
|
||||||
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
|
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
|
||||||
@ -549,10 +568,11 @@ class core extends common
|
|||||||
}
|
}
|
||||||
// Accès concurrent stocke la page visitée
|
// Accès concurrent stocke la page visitée
|
||||||
if (
|
if (
|
||||||
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
$this->isConnected() === true
|
||||||
&& $this->getUser('id')
|
&& $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()]);
|
$this->setData(['user', $this->getUser('id'), 'accessTimer', time()]);
|
||||||
}
|
}
|
||||||
// Breadcrumb
|
// Breadcrumb
|
||||||
@ -576,10 +596,10 @@ class core extends common
|
|||||||
$inlineScript[] = $this->getData(['page', $this->getUrl(0), 'js']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'js']);
|
$inlineScript[] = $this->getData(['page', $this->getUrl(0), 'js']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'js']);
|
||||||
|
|
||||||
// Importe le contenu, le CSS et le script des barres
|
// Importe le contenu, le CSS et le script des barres
|
||||||
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), self::$siteContent) : '';
|
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), common::$siteContent) : '';
|
||||||
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']);
|
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']);
|
||||||
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']);
|
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']);
|
||||||
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), self::$siteContent) : '';
|
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), common::$siteContent) : '';
|
||||||
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']);
|
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']);
|
||||||
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']);
|
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']);
|
||||||
|
|
||||||
@ -597,7 +617,7 @@ class core extends common
|
|||||||
|
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'content' => $this->getPage($this->getUrl(0), self::$siteContent),
|
'content' => $this->getPage($this->getUrl(0), common::$siteContent),
|
||||||
'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
|
'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
|
||||||
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
|
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
|
||||||
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
|
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
|
||||||
@ -623,7 +643,7 @@ class core extends common
|
|||||||
: $this->getData(['page', $this->getUrl(0), 'metaDescription']);
|
: $this->getData(['page', $this->getUrl(0), 'metaDescription']);
|
||||||
|
|
||||||
// Importe le CSS de la page principale
|
// Importe le CSS de la page principale
|
||||||
$pageContent = $this->getPage($this->getUrl(0), self::$siteContent);
|
$pageContent = $this->getPage($this->getUrl(0), common::$siteContent);
|
||||||
|
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
@ -668,8 +688,8 @@ class core extends common
|
|||||||
$output = $module->output;
|
$output = $module->output;
|
||||||
// Check le groupe de l'utilisateur
|
// Check le groupe de l'utilisateur
|
||||||
if (
|
if (
|
||||||
($module::$actions[$action] === self::GROUP_VISITOR
|
($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('group') >= $module::$actions[$action]
|
||||||
and $this->getUser('permission', $moduleId, $action)
|
and $this->getUser('permission', $moduleId, $action)
|
||||||
)
|
)
|
||||||
@ -681,10 +701,10 @@ class core extends common
|
|||||||
foreach ($_POST as $postId => $postValue) {
|
foreach ($_POST as $postId => $postValue) {
|
||||||
if (is_array($postValue)) {
|
if (is_array($postValue)) {
|
||||||
foreach ($postValue as $subPostId => $subPostValue) {
|
foreach ($postValue as $subPostId => $subPostValue) {
|
||||||
self::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
|
common::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self::$inputBefore[$postId] = $postValue;
|
common::$inputBefore[$postId] = $postValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,9 +744,9 @@ class core extends common
|
|||||||
// Contenu par vue
|
// Contenu par vue
|
||||||
elseif ($output['view']) {
|
elseif ($output['view']) {
|
||||||
// Chemin en fonction d'un module du coeur ou d'un module
|
// Chemin en fonction d'un module du coeur ou d'un module
|
||||||
$modulePath = in_array($moduleId, self::$coreModuleIds) ? 'core/' : '';
|
$modulePath = in_array($moduleId, common::$coreModuleIds) ? 'core/' : '';
|
||||||
// CSS
|
// CSS
|
||||||
$stylePath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
|
$stylePath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
|
||||||
if (file_exists($stylePath)) {
|
if (file_exists($stylePath)) {
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'style' => file_get_contents($stylePath)
|
'style' => file_get_contents($stylePath)
|
||||||
@ -739,7 +759,7 @@ class core extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JS
|
// JS
|
||||||
$scriptPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
|
$scriptPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
|
||||||
if (file_exists($scriptPath)) {
|
if (file_exists($scriptPath)) {
|
||||||
ob_start();
|
ob_start();
|
||||||
include $scriptPath;
|
include $scriptPath;
|
||||||
@ -748,7 +768,7 @@ class core extends common
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
// Vue
|
// Vue
|
||||||
$viewPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
|
$viewPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
|
||||||
if (file_exists($viewPath)) {
|
if (file_exists($viewPath)) {
|
||||||
ob_start();
|
ob_start();
|
||||||
include $viewPath;
|
include $viewPath;
|
||||||
@ -757,7 +777,7 @@ class core extends common
|
|||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'content' => ob_get_clean() . ($output['showPageContent'] ? $pageContent : '')
|
'content' => ob_get_clean() . ($output['showPageContent'] ? $pageContent : '')
|
||||||
]);
|
]);
|
||||||
} else if ($modpos === 'free') {
|
} elseif ($modpos === 'free' && strstr($pageContent, '[MODULE]')) {
|
||||||
if (strstr($pageContent, '[MODULE]', true) === false) {
|
if (strstr($pageContent, '[MODULE]', true) === false) {
|
||||||
$begin = strstr($pageContent, '[]', true);
|
$begin = strstr($pageContent, '[]', true);
|
||||||
} else {
|
} else {
|
||||||
@ -817,7 +837,7 @@ class core extends common
|
|||||||
if ($accessInfo['userName']) {
|
if ($accessInfo['userName']) {
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => 'Accès verrouillé',
|
'title' => 'Accès verrouillé',
|
||||||
'content' => template::speech('<p>'. sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s</p><p><a style="color:inherit" href="javascript:history.back()">%s</a></p>'), $accessInfo['pageId'], $accessInfo['userName'], helper::translate('Retour')))
|
'content' => template::speech('<p>' . sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s</p><p><a style="color:inherit" href="javascript:history.back()">%s</a></p>'), $accessInfo['pageId'], $accessInfo['userName'], helper::translate('Retour')))
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
@ -829,22 +849,49 @@ class core extends common
|
|||||||
} else {
|
} else {
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => 'Accès interdit',
|
'title' => 'Accès interdit',
|
||||||
'content' => template::speech('<p>' . helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') . '</p><p><a style="color:inherit" href="javascript:history.back()">'. helper::translate('Retour') . '</a></p>')
|
'content' => template::speech('<p>' . helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($this->output['content'] === '') {
|
} elseif ($this->output['content'] === '') {
|
||||||
|
|
||||||
|
// Pour éviter une 404, bascule dans l'espace correct si la page existe dans cet espace.
|
||||||
|
// Parcourir les espaces y compris l'accueil
|
||||||
|
foreach (array_merge(['home' => []], $this->getData(['course'])) as $courseId => $value) {
|
||||||
|
;
|
||||||
|
if (
|
||||||
|
// l'espace existe
|
||||||
|
is_dir(common::DATA_DIR . $courseId) &&
|
||||||
|
file_exists(common::DATA_DIR . $courseId . '/page.json')
|
||||||
|
) {
|
||||||
|
// Lire les données des pages
|
||||||
|
$pagesId = json_decode(file_get_contents(common::DATA_DIR . $courseId . '/page.json'), true);
|
||||||
|
if (
|
||||||
|
// La page existe
|
||||||
|
is_array($pagesId['page']) &&
|
||||||
|
array_key_exists($this->getUrl(0), $pagesId['page'])
|
||||||
|
) {
|
||||||
|
// Basculer
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = $courseId;
|
||||||
|
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// La page n'existe pas dans les esapces, on génére une erreur 404
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
if (
|
if (
|
||||||
|
// une page est définie dans la configuration mais dans home
|
||||||
$this->getData(['config', 'page404']) !== 'none'
|
$this->getData(['config', 'page404']) !== 'none'
|
||||||
//and $this->getData(['page', $this->getData(['config', 'page404'])])
|
|
||||||
) {
|
) {
|
||||||
|
// Bascule sur l'acccueil et rediriger
|
||||||
$_SESSION['ZWII_SITE_CONTENT'] = 'home';
|
$_SESSION['ZWII_SITE_CONTENT'] = 'home';
|
||||||
header('Location:' . helper::baseUrl() . $this->getData(['config', 'page404']));
|
header('Location:' . helper::baseUrl() . $this->getData(['config', 'page404']));
|
||||||
} else {
|
} else {
|
||||||
|
// Page par défaut
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => 'Page indisponible',
|
'title' => 'Page indisponible',
|
||||||
'content' => template::speech('<p>' . helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)') . '</p><p><a style="color:inherit" href="javascript:history.back()">'. helper::translate('Retour') . '</a></p>')
|
'content' => template::speech('<p>' . helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,25 +914,25 @@ class core extends common
|
|||||||
}
|
}
|
||||||
switch ($this->output['display']) {
|
switch ($this->output['display']) {
|
||||||
// Layout brut
|
// Layout brut
|
||||||
case self::DISPLAY_RAW:
|
case common::DISPLAY_RAW:
|
||||||
echo $this->output['content'];
|
echo $this->output['content'];
|
||||||
break;
|
break;
|
||||||
// Layout vide
|
// Layout vide
|
||||||
case self::DISPLAY_LAYOUT_BLANK:
|
case common::DISPLAY_LAYOUT_BLANK:
|
||||||
require 'core/layout/blank.php';
|
require 'core/layout/blank.php';
|
||||||
break;
|
break;
|
||||||
// Affichage en JSON
|
// Affichage en JSON
|
||||||
case self::DISPLAY_JSON:
|
case common::DISPLAY_JSON:
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode($this->output['content']);
|
echo json_encode($this->output['content']);
|
||||||
break;
|
break;
|
||||||
// RSS feed
|
// RSS feed
|
||||||
case self::DISPLAY_RSS:
|
case common::DISPLAY_RSS:
|
||||||
header('Content-type: application/rss+xml; charset=UTF-8');
|
header('Content-type: application/rss+xml; charset=UTF-8');
|
||||||
echo $this->output['content'];
|
echo $this->output['content'];
|
||||||
break;
|
break;
|
||||||
// Layout allégé
|
// Layout allégé
|
||||||
case self::DISPLAY_LAYOUT_LIGHT:
|
case common::DISPLAY_LAYOUT_LIGHT:
|
||||||
ob_start();
|
ob_start();
|
||||||
require 'core/layout/light.php';
|
require 'core/layout/light.php';
|
||||||
$content = ob_get_clean();
|
$content = ob_get_clean();
|
||||||
@ -896,7 +943,7 @@ class core extends common
|
|||||||
echo $content;
|
echo $content;
|
||||||
break;
|
break;
|
||||||
// Layout principal
|
// Layout principal
|
||||||
case self::DISPLAY_LAYOUT_MAIN:
|
case common::DISPLAY_LAYOUT_MAIN:
|
||||||
ob_start();
|
ob_start();
|
||||||
require 'core/layout/main.php';
|
require 'core/layout/main.php';
|
||||||
$content = ob_get_clean();
|
$content = ob_get_clean();
|
||||||
|
@ -128,7 +128,17 @@ class SitemapGenerator
|
|||||||
*/
|
*/
|
||||||
private $sampleRobotsLines = [
|
private $sampleRobotsLines = [
|
||||||
"User-agent: *",
|
"User-agent: *",
|
||||||
|
"Disallow: /",
|
||||||
|
"User-agent: Googlebot",
|
||||||
"Allow: /",
|
"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
|
* @var array list of valid changefreq values according to the spec
|
||||||
|
@ -28,7 +28,7 @@ class template
|
|||||||
$attributes['value'] = helper::translate($attributes['value']);
|
$attributes['value'] = helper::translate($attributes['value']);
|
||||||
$attributes['help'] = helper::translate($attributes['help']);
|
$attributes['help'] = helper::translate($attributes['help']);
|
||||||
// Retourne le html
|
// Retourne le html
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<a %s class="button %s %s %s" %s>%s</a>',
|
'<a %s class="button %s %s %s" %s>%s</a>',
|
||||||
helper::sprintAttributes($attributes, ['class', 'disabled', 'ico', 'value']),
|
helper::sprintAttributes($attributes, ['class', 'disabled', 'ico', 'value']),
|
||||||
$attributes['disabled'] ? 'disabled' : '',
|
$attributes['disabled'] ? 'disabled' : '',
|
||||||
@ -65,12 +65,12 @@ class template
|
|||||||
// Limite addition et soustraction selon le type de captcha
|
// Limite addition et soustraction selon le type de captcha
|
||||||
$numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
$numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||||
$letters = ['u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'];
|
$letters = ['u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'];
|
||||||
$limit = $attributes['limit'] ? count($letters) - 1 : 10;
|
$limit = $attributes['limit'] ? count($letters) - 1 : 10;
|
||||||
|
|
||||||
// Tirage de l'opération
|
// Tirage de l'opération
|
||||||
mt_srand();
|
mt_srand();
|
||||||
// Captcha simple limité à l'addition
|
// Captcha simple limité à l'addition
|
||||||
$operator = $attributes['limit'] ? mt_rand(1, 4) : 1;
|
$operator = $attributes['limit'] ? mt_rand(1, 4) : 1;
|
||||||
|
|
||||||
// Limite si multiplication ou division
|
// Limite si multiplication ou division
|
||||||
if ($operator > 2) {
|
if ($operator > 2) {
|
||||||
@ -94,15 +94,15 @@ class template
|
|||||||
switch ($operator) {
|
switch ($operator) {
|
||||||
case 1:
|
case 1:
|
||||||
$operator = template::ico('plus', ['fontSize' => '2em;']);
|
$operator = template::ico('plus', ['fontSize' => '2em;']);
|
||||||
$result = $firstNumber + $secondNumber;
|
$result = $firstNumber + $secondNumber;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
$operator = template::ico('minus', ['fontSize' => '2em;']);
|
$operator = template::ico('minus', ['fontSize' => '2em;']);
|
||||||
$result = $firstNumber - $secondNumber;
|
$result = $firstNumber - $secondNumber;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
$operator = template::ico('cancel', ['fontSize' => '2em;']);
|
$operator = template::ico('cancel', ['fontSize' => '2em;']);
|
||||||
$result = $firstNumber * $secondNumber;
|
$result = $firstNumber * $secondNumber;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
$operator = template::ico('divide', ['fontSize' => '2em;']);
|
$operator = template::ico('divide', ['fontSize' => '2em;']);
|
||||||
@ -112,7 +112,7 @@ class template
|
|||||||
}
|
}
|
||||||
mt_srand();
|
mt_srand();
|
||||||
$secondNumber = mt_rand(1, $limit);
|
$secondNumber = mt_rand(1, $limit);
|
||||||
$firstNumber = $firstNumber * $secondNumber;
|
$firstNumber = $firstNumber * $secondNumber;
|
||||||
$result = $firstNumber / $secondNumber;
|
$result = $firstNumber / $secondNumber;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -125,8 +125,8 @@ class template
|
|||||||
$secondLetter = uniqid();
|
$secondLetter = uniqid();
|
||||||
|
|
||||||
// Masquage image source pour éviter un décodage
|
// Masquage image source pour éviter un décodage
|
||||||
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
|
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
|
||||||
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
|
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
|
||||||
|
|
||||||
|
|
||||||
// Début du wrapper
|
// Début du wrapper
|
||||||
@ -134,7 +134,7 @@ class template
|
|||||||
// Label
|
// Label
|
||||||
$html .= self::label(
|
$html .= self::label(
|
||||||
$attributes['id'],
|
$attributes['id'],
|
||||||
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" /> <strong>' . $operator . '</strong> <img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" />' . template::ico('eq', ['fontSize' => '2em;']),
|
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" /> <strong>' . $operator . '</strong> <img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" />' . template::ico('eq', ['fontSize' => '2em;']),
|
||||||
[
|
[
|
||||||
'help' => $attributes['help']
|
'help' => $attributes['help']
|
||||||
]
|
]
|
||||||
@ -224,7 +224,7 @@ class template
|
|||||||
* Crée un champ date
|
* Crée un champ date
|
||||||
* @param string $nameId Nom et id du champ
|
* @param string $nameId Nom et id du champ
|
||||||
* @param array $attributes Attributs ($key => $value)
|
* @param array $attributes Attributs ($key => $value)
|
||||||
* @param string type date time datetime-local month week
|
* @param string type date seule ; time heure seule ; datetime-local (jour et heure)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function date($nameId, array $attributes = [])
|
public static function date($nameId, array $attributes = [])
|
||||||
@ -244,17 +244,32 @@ class template
|
|||||||
'placeholder' => '',
|
'placeholder' => '',
|
||||||
'readonly' => false,
|
'readonly' => false,
|
||||||
'value' => '',
|
'value' => '',
|
||||||
'type'=> 'date',
|
'type' => 'date',
|
||||||
], $attributes);
|
], $attributes);
|
||||||
// Traduction de l'aide et de l'étiquette
|
// Traduction de l'aide et de l'étiquette
|
||||||
$attributes['label'] = helper::translate($attributes['label']);
|
$attributes['label'] = helper::translate($attributes['label']);
|
||||||
$attributes['help'] = helper::translate($attributes['help']);
|
$attributes['help'] = helper::translate($attributes['help']);
|
||||||
//$attributes['placeholder'] = helper::translate($attributes['placeholder']);
|
//$attributes['placeholder'] = helper::translate($attributes['placeholder']);
|
||||||
|
// Filtre selon le type
|
||||||
|
switch ($attributes['type']) {
|
||||||
|
case 'datetime-local':
|
||||||
|
$filter = helper::FILTER_TIMESTAMP;
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
$filter = helper::FILTER_DATE; // Pour générer une valeur uniquement sur la date
|
||||||
|
break;
|
||||||
|
case 'time':
|
||||||
|
$filter = helper::FILTER_TIME; // Pour générer une valeur uniquement sur l'heure
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$filter = null; // pas de filtre pour month and year
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Sauvegarde des données en cas d'erreur
|
// Sauvegarde des données en cas d'erreur
|
||||||
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
|
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||||
} else {
|
} else {
|
||||||
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], helper::FILTER_TIMESTAMP) : '');
|
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], $filter) : '');
|
||||||
}
|
}
|
||||||
// Début du wrapper
|
// Début du wrapper
|
||||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||||
@ -284,7 +299,7 @@ class template
|
|||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
// Retourne le html
|
// Retourne le html
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,6 +325,7 @@ class template
|
|||||||
'name' => $nameId,
|
'name' => $nameId,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
'value' => '',
|
'value' => '',
|
||||||
|
'folder' => '',
|
||||||
'language' => 'fr_FR'
|
'language' => 'fr_FR'
|
||||||
], $attributes);
|
], $attributes);
|
||||||
// Traduction de l'aide et de l'étiquette
|
// Traduction de l'aide et de l'étiquette
|
||||||
@ -346,14 +362,16 @@ class template
|
|||||||
$html .= sprintf(
|
$html .= sprintf(
|
||||||
'<a
|
'<a
|
||||||
href="' .
|
href="' .
|
||||||
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
|
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
|
||||||
'?relative_url=1' .
|
'?relative_url=1' .
|
||||||
'&lang=' . $attributes['language'] .
|
'&lang=' . $attributes['language'] .
|
||||||
'&field_id=' . $attributes['id'] .
|
'&field_id=' . $attributes['id'] .
|
||||||
'&type=' . $attributes['type'] .
|
'&type=' . $attributes['type'] .
|
||||||
'&akey=' . md5_file(core::DATA_DIR . 'core.json') .
|
'&akey=' . md5_file(core::DATA_DIR . 'core.json') .
|
||||||
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
|
// Ajoute le nom du dossier si la variable est passée
|
||||||
. '"
|
(!empty($attributes['folder']) ? '&fldr=' . $attributes['folder'] : '') .
|
||||||
|
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
|
||||||
|
. '"
|
||||||
class="inputFile %s %s"
|
class="inputFile %s %s"
|
||||||
%s
|
%s
|
||||||
data-lity
|
data-lity
|
||||||
@ -471,7 +489,7 @@ class template
|
|||||||
// Traduction de l'aide
|
// Traduction de l'aide
|
||||||
$attributes['help'] = helper::translate($attributes['help']);
|
$attributes['help'] = helper::translate($attributes['help']);
|
||||||
// Contenu de l'icône
|
// Contenu de l'icône
|
||||||
$alt = $attributes['help'] ? $attributes['help'] : $ico;
|
$alt = $attributes['help'] ? $attributes['help'] : $ico;
|
||||||
$item = $attributes['href'] ? '<a id="' . $attributes['id'] . '" data-tippy-content="' . $attributes['help'] . '" alt="' . $alt . '" href="' . $attributes['href'] . '" ' . $attributes['attr'] . ' >' : '';
|
$item = $attributes['href'] ? '<a id="' . $attributes['id'] . '" data-tippy-content="' . $attributes['help'] . '" alt="' . $alt . '" href="' . $attributes['href'] . '" ' . $attributes['attr'] . ' >' : '';
|
||||||
$item .= '<span class="zwiico-' . $ico . ($attributes['margin'] ? ' zwiico-margin-' . $attributes['margin'] : '') . ($attributes['animate'] ? ' animate-spin' : '') . '" style="font-size:' . $attributes['fontSize'] . '"><!----></span>';
|
$item .= '<span class="zwiico-' . $ico . ($attributes['margin'] ? ' zwiico-margin-' . $attributes['margin'] : '') . ($attributes['animate'] ? ' animate-spin' : '') . '" style="font-size:' . $attributes['fontSize'] . '"><!----></span>';
|
||||||
$item .= ($attributes['href']) ? '</a>' : '';
|
$item .= ($attributes['href']) ? '</a>' : '';
|
||||||
@ -486,7 +504,7 @@ class template
|
|||||||
*/
|
*/
|
||||||
public static function flag($langId, $size = 'auto')
|
public static function flag($langId, $size = 'auto')
|
||||||
{
|
{
|
||||||
$lang = 'home';
|
$lang = 'fr_FR';
|
||||||
switch ($langId) {
|
switch ($langId) {
|
||||||
case '':
|
case '':
|
||||||
break;
|
break;
|
||||||
@ -496,6 +514,8 @@ class template
|
|||||||
case 'selected':
|
case 'selected':
|
||||||
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
|
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
|
||||||
$lang = $_SESSION['ZWII_SITE_CONTENT'];
|
$lang = $_SESSION['ZWII_SITE_CONTENT'];
|
||||||
|
} else {
|
||||||
|
$lang = 'fr_FR';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '<img class="flag" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"
|
return '<img class="flag" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"
|
||||||
@ -684,12 +704,12 @@ class template
|
|||||||
'label' => '',
|
'label' => '',
|
||||||
'name' => $nameId,
|
'name' => $nameId,
|
||||||
'selected' => '',
|
'selected' => '',
|
||||||
'font' => [],
|
'font' => [],
|
||||||
'multiple' => ''
|
'multiple' => ''
|
||||||
], $attributes);
|
], $attributes);
|
||||||
// Traduction de l'aide et de l'étiquette
|
// Traduction de l'aide et de l'étiquette
|
||||||
$attributes['label'] = helper::translate($attributes['label']);
|
$attributes['label'] = helper::translate($attributes['label']);
|
||||||
$attributes['help'] = helper::translate($attributes['help']);
|
$attributes['help'] = helper::translate($attributes['help']);
|
||||||
// Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes
|
// Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes
|
||||||
if (empty($attributes['font']) === false) {
|
if (empty($attributes['font']) === false) {
|
||||||
$fonts = $attributes['font'];
|
$fonts = $attributes['font'];
|
||||||
@ -726,7 +746,7 @@ class template
|
|||||||
);
|
);
|
||||||
foreach ($options as $value => $text) {
|
foreach ($options as $value => $text) {
|
||||||
// Select des liste de fontes
|
// Select des liste de fontes
|
||||||
$html .= isset($fonts) ? sprintf(
|
$html .= isset($fonts) ? sprintf(
|
||||||
'<option value="%s"%s style="font-family: %s;">%s</option>',
|
'<option value="%s"%s style="font-family: %s;">%s</option>',
|
||||||
$value,
|
$value,
|
||||||
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
|
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
|
||||||
@ -748,6 +768,7 @@ class template
|
|||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crée une bulle de dialogue
|
* Crée une bulle de dialogue
|
||||||
* @param string $text Texte de la bulle
|
* @param string $text Texte de la bulle
|
||||||
@ -779,7 +800,7 @@ class template
|
|||||||
// Traduction de l'aide et de l'étiquette
|
// Traduction de l'aide et de l'étiquette
|
||||||
$attributes['value'] = helper::translate($attributes['value']);
|
$attributes['value'] = helper::translate($attributes['value']);
|
||||||
// Retourne le html
|
// Retourne le html
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<button type="submit" class="%s%s" %s>%s</button>',
|
'<button type="submit" class="%s%s" %s>%s</button>',
|
||||||
$attributes['class'],
|
$attributes['class'],
|
||||||
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
|
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
|
||||||
@ -807,7 +828,7 @@ class template
|
|||||||
], $attributes);
|
], $attributes);
|
||||||
// Traduction de l'aide et de l'étiquette
|
// Traduction de l'aide et de l'étiquette
|
||||||
foreach ($head as $value) {
|
foreach ($head as $value) {
|
||||||
$head[array_search($value, $head)] = helper::translate($value);
|
$head[array_search($value, $head)] = helper::translate($value);
|
||||||
}
|
}
|
||||||
// Début du wrapper
|
// Début du wrapper
|
||||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="tableWrapper ' . $attributes['classWrapper'] . '">';
|
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="tableWrapper ' . $attributes['classWrapper'] . '">';
|
||||||
@ -902,7 +923,7 @@ class template
|
|||||||
$html .= self::notice($attributes['id'], $notice);
|
$html .= self::notice($attributes['id'], $notice);
|
||||||
// Texte
|
// Texte
|
||||||
$html .= sprintf(
|
$html .= sprintf(
|
||||||
'<input type="' . $attributes['type']. '" %s>',
|
'<input type="' . $attributes['type'] . '" %s>',
|
||||||
helper::sprintAttributes($attributes)
|
helper::sprintAttributes($attributes)
|
||||||
);
|
);
|
||||||
// Fin du wrapper
|
// Fin du wrapper
|
||||||
|
@ -216,15 +216,16 @@ core.start = function () {
|
|||||||
// Variables des cookies
|
// Variables des cookies
|
||||||
var getUrl = window.location;
|
var getUrl = window.location;
|
||||||
var domain = "domain=" + getUrl.hostname + ";";
|
var domain = "domain=" + getUrl.hostname + ";";
|
||||||
|
var basePath = getUrl.pathname.substring(0, getUrl.pathname.lastIndexOf('/') + 1);
|
||||||
|
var path = "path=" + basePath + ";";
|
||||||
var e = new Date();
|
var e = new Date();
|
||||||
e.setFullYear(e.getFullYear() + 1);
|
e.setFullYear(e.getFullYear() + 1);
|
||||||
var expires = "expires=" + e.toUTCString();
|
var expires = "expires=" + e.toUTCString() + ";";
|
||||||
|
|
||||||
// Stocke le cookie d'acceptation
|
// 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
|
* Fermeture de la popup des cookies
|
||||||
*/
|
*/
|
||||||
@ -462,7 +463,7 @@ $(document).ready(function () {
|
|||||||
/**
|
/**
|
||||||
* Chargement paresseux des images et des iframes
|
* Chargement paresseux des images et des iframes
|
||||||
*/
|
*/
|
||||||
$("img,picture,iframe").attr("loading", "lazy");
|
$("img").attr("loading", "lazy");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Effet accordéon
|
* Effet accordéon
|
||||||
|
183
core/core.php
183
core/core.php
@ -51,7 +51,7 @@ class common
|
|||||||
const ACCESS_TIMER = 1800;
|
const ACCESS_TIMER = 1800;
|
||||||
|
|
||||||
// Numéro de version
|
// Numéro de version
|
||||||
const ZWII_VERSION = '1.7.04';
|
const ZWII_VERSION = '1.14.08';
|
||||||
|
|
||||||
// URL autoupdate
|
// URL autoupdate
|
||||||
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/campus-update/raw/branch/master/';
|
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/campus-update/raw/branch/master/';
|
||||||
@ -174,8 +174,12 @@ class common
|
|||||||
public static $dialog;
|
public static $dialog;
|
||||||
// Langue de l'interface sélectionnée
|
// Langue de l'interface sélectionnée
|
||||||
public static $i18nUI = 'fr_FR';
|
public static $i18nUI = 'fr_FR';
|
||||||
// Langues de contenu
|
|
||||||
|
// Espace, contenu sélectionné
|
||||||
public static $siteContent = 'home';
|
public static $siteContent = 'home';
|
||||||
|
// Progression d'un participant
|
||||||
|
public static $userProgress = '';
|
||||||
|
|
||||||
public static $languages = [
|
public static $languages = [
|
||||||
'de' => 'Deutsch',
|
'de' => 'Deutsch',
|
||||||
'en_EN' => 'English',
|
'en_EN' => 'English',
|
||||||
@ -319,28 +323,57 @@ class common
|
|||||||
public function __construct()
|
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
|
// Extraction des données http
|
||||||
if (isset($_POST)) {
|
if (isset($_POST)) {
|
||||||
$this->input['_POST'] = $_POST;
|
$this->input['_POST'] = $_POST;
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['input']['_POST'] = $this->input['_POST'];
|
||||||
}
|
}
|
||||||
if (isset($_COOKIE)) {
|
if (isset($_COOKIE)) {
|
||||||
$this->input['_COOKIE'] = $_COOKIE;
|
$this->input['_COOKIE'] = $_COOKIE;
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['input']['_COOKIE'] = $this->input['_COOKIE'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Déterminer le contenu du site
|
// Déterminer le contenu du site
|
||||||
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
|
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
|
||||||
// Déterminé par la session présente
|
// Déterminé par la session présente
|
||||||
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT'];
|
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
|
// Instanciation de la classe des entrées / sorties
|
||||||
// Les fichiers de configuration
|
// Les fichiers de configuration
|
||||||
foreach ($this->configFiles as $module => $value) {
|
foreach ($this->configFiles as $module => $value) {
|
||||||
$this->initDB($module);
|
$this->initDB($module);
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['configFiles'] = $this->configFiles;
|
||||||
// Les fichiers des contenus
|
// Les fichiers des contenus
|
||||||
foreach ($this->contentFiles as $module => $value) {
|
foreach ($this->contentFiles as $module => $value) {
|
||||||
$this->initDB($module, self::$siteContent);
|
$this->initDB($module, self::$siteContent);
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['dataFiles'] = $this->dataFiles;
|
||||||
|
|
||||||
|
|
||||||
// Installation fraîche, initialisation de la configuration inexistante
|
// Installation fraîche, initialisation de la configuration inexistante
|
||||||
@ -367,6 +400,8 @@ class common
|
|||||||
if ($this->user === []) {
|
if ($this->user === []) {
|
||||||
$this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]);
|
$this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]);
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['user'] = $this->user;
|
||||||
|
|
||||||
// Langue de l'administration si le user est connecté
|
// Langue de l'administration si le user est connecté
|
||||||
if ($this->getData(['user', $this->getUser('id'), 'language'])) {
|
if ($this->getData(['user', $this->getUser('id'), 'language'])) {
|
||||||
@ -389,13 +424,17 @@ class common
|
|||||||
// Stocker le cookie de langue pour l'éditeur de texte ainsi que l'url du contenu pour le theme
|
// 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);
|
setcookie('ZWII_UI', self::$i18nUI, time() + 3600, '', '', false, false);
|
||||||
// Stocker l'courseId pour le thème de TinyMCE
|
// 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);
|
setlocale(LC_ALL, self::$i18nUI);
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['i18nUI'] = self::$i18nUI;
|
||||||
|
|
||||||
// Construit la liste des pages parents/enfants
|
// Construit la liste des pages parents/enfants
|
||||||
if ($this->hierarchy['all'] === []) {
|
if ($this->hierarchy['all'] === []) {
|
||||||
$this->buildHierarchy();
|
$this->buildHierarchy();
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['hierarchy'] = $this->hierarchy;
|
||||||
|
|
||||||
// Construit l'url
|
// Construit l'url
|
||||||
if ($this->url === '') {
|
if ($this->url === '') {
|
||||||
@ -405,6 +444,8 @@ class common
|
|||||||
$this->url = $this->homePageId();
|
$this->url = $this->homePageId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['url'] = $this->url;
|
||||||
|
|
||||||
// Chargement des dialogues
|
// Chargement des dialogues
|
||||||
if (!file_exists(self::I18N_DIR . self::$i18nUI . '.json')) {
|
if (!file_exists(self::I18N_DIR . self::$i18nUI . '.json')) {
|
||||||
@ -424,6 +465,8 @@ class common
|
|||||||
self::$dialog = array_merge(self::$dialog, $d);
|
self::$dialog = array_merge(self::$dialog, $d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Cache
|
||||||
|
$GLOBALS['common_construct']['dialog'] = self::$dialog;
|
||||||
|
|
||||||
// Données de proxy
|
// Données de proxy
|
||||||
$proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']);
|
$proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']);
|
||||||
@ -451,8 +494,6 @@ class common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ajoute les valeurs en sortie
|
* Ajoute les valeurs en sortie
|
||||||
* @param array $output Valeurs en sortie
|
* @param array $output Valeurs en sortie
|
||||||
@ -512,8 +553,10 @@ class common
|
|||||||
/**
|
/**
|
||||||
* Sauvegarde des données
|
* Sauvegarde des données
|
||||||
* @param array $keys Clé(s) 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
|
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
|
||||||
if (
|
if (
|
||||||
@ -541,11 +584,12 @@ class common
|
|||||||
$query .= '.' . $keys[$i];
|
$query .= '.' . $keys[$i];
|
||||||
}
|
}
|
||||||
// Appliquer la modification, le dernier élément étant la donnée à sauvegarder
|
// 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;
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accède aux données
|
* Accède aux données
|
||||||
* @param array $keys Clé(s) des données
|
* @param array $keys Clé(s) des données
|
||||||
@ -589,13 +633,13 @@ class common
|
|||||||
/**
|
/**
|
||||||
* Ecrire les données de la page
|
* Ecrire les données de la page
|
||||||
* @param string pageId
|
* @param string pageId
|
||||||
* @param string contenu de la page
|
* @param array contenu de la page
|
||||||
* @return int nombre d'octets écrits ou erreur
|
* @return int nombre d'octets écrits ou erreur
|
||||||
*/
|
*/
|
||||||
public function setPage($page, $value, $path)
|
public function setPage($page, $value, $path)
|
||||||
{
|
{
|
||||||
|
|
||||||
return file_put_contents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value);
|
return $this->secure_file_put_contents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -611,18 +655,74 @@ class common
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Écrit les données dans un fichier avec plusieurs tentatives d'écriture et verrouillage
|
||||||
|
*
|
||||||
|
* @param string $filename Le nom du fichier
|
||||||
|
* @param string $data Les données à écrire dans le fichier
|
||||||
|
* @param int $flags Les drapeaux optionnels à passer à la fonction $this->secure_file_put_contents
|
||||||
|
* @return bool True si l'écriture a réussi, sinon false
|
||||||
|
*/
|
||||||
|
function secure_file_put_contents($filename, $data, $flags = 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Initialise le compteur de tentatives
|
||||||
|
$attempts = 0;
|
||||||
|
|
||||||
|
// Vérifie la longueur des données
|
||||||
|
$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
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incrémente le compteur de tentatives
|
||||||
|
$attempts++;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
// Etat de l'écriture
|
||||||
|
return ($attempts < 5);
|
||||||
|
}
|
||||||
|
|
||||||
public function initDB($module, $path = '')
|
public function initDB($module, $path = '')
|
||||||
{
|
{
|
||||||
// Instanciation de la classe des entrées / sorties
|
// Chemin complet vers le fichier JSON
|
||||||
// Constructeur JsonDB;
|
$dir = empty($path) ? self::DATA_DIR : self::DATA_DIR . $path . '/';
|
||||||
$this->dataFiles[$module] = new \Prowebcraft\JsonDb([
|
$config = [
|
||||||
'name' => $module . '.json',
|
'name' => $module . '.json',
|
||||||
'dir' => self::DATA_DIR . $path . '/',
|
'dir' => $dir,
|
||||||
'backup' => file_exists('site/data/.backup')
|
'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
|
* Initialisation des données sur un contenu ou la page d'accueil
|
||||||
* @param string $course : id du module à générer
|
* @param string $course : id du module à générer
|
||||||
@ -705,7 +805,7 @@ class common
|
|||||||
* Fonction pour construire le tableau des pages
|
* Fonction pour construire le tableau des pages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function buildHierarchy()
|
public function buildHierarchy()
|
||||||
{
|
{
|
||||||
|
|
||||||
$pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC');
|
$pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC');
|
||||||
@ -713,10 +813,10 @@ class common
|
|||||||
foreach ($pages as $pageId => $pagePosition) {
|
foreach ($pages as $pageId => $pagePosition) {
|
||||||
if (
|
if (
|
||||||
// Page parent
|
// Page parent
|
||||||
$this->getData(['page', $pageId, 'parentPageId']) === ''
|
$this->getData(['page', $pageId, 'parentPageId']) === ""
|
||||||
// Ignore les pages dont l'utilisateur n'a pas accès
|
// Ignore les pages dont l'utilisateur n'a pas accès
|
||||||
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
|
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
|
||||||
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
or ($this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY')
|
||||||
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
|
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
|
||||||
// Modification qui tient compte du profil de la page
|
// 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']))
|
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
|
||||||
@ -735,21 +835,21 @@ class common
|
|||||||
}
|
}
|
||||||
// Enfants
|
// Enfants
|
||||||
foreach ($pages as $pageId => $pagePosition) {
|
foreach ($pages as $pageId => $pagePosition) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// Page parent
|
// Page parent
|
||||||
$parentId = $this->getData(['page', $pageId, 'parentPageId'])
|
$parentId = $this->getData(['page', $pageId, 'parentPageId'])
|
||||||
// Ignore les pages dont l'utilisateur n'a pas accès
|
// Ignore les pages dont l'utilisateur n'a pas accès
|
||||||
and (
|
and (
|
||||||
($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
|
(
|
||||||
and $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
|
$this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
|
||||||
|
and
|
||||||
|
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
|
||||||
)
|
)
|
||||||
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
|
or (
|
||||||
//and $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])
|
$this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY')
|
||||||
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
|
and
|
||||||
|
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])
|
||||||
// Modification qui tient compte du profil de la page
|
|
||||||
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $this->$parentId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $this->$parentId, 'profil']))
|
|
||||||
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $this->$pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
|
|
||||||
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -973,6 +1073,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
|
* Check qu'une valeur est transmise par la méthode _POST
|
||||||
* @return bool
|
* @return bool
|
||||||
@ -1063,8 +1174,9 @@ class common
|
|||||||
}
|
}
|
||||||
// Articles du blog
|
// Articles du blog
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog' &&
|
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog'
|
||||||
!empty($this->getData(['module', $parentPageId]))
|
&& !empty($this->getData(['module', $parentPageId]))
|
||||||
|
&& $this->getData(['module', $parentPageId, 'posts'])
|
||||||
) {
|
) {
|
||||||
foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) {
|
foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) {
|
||||||
if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) {
|
if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) {
|
||||||
@ -1161,8 +1273,7 @@ class common
|
|||||||
$source_image = imagecreatefromwebp($src);
|
$source_image = imagecreatefromwebp($src);
|
||||||
break;
|
break;
|
||||||
case 'avif':
|
case 'avif':
|
||||||
$source_image = function_exists('imagecreatefromavif') ? imagecreatefromavif($src) : null;
|
$source_image = imagecreatefromavif($src);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Image valide
|
// Image valide
|
||||||
if ($source_image) {
|
if ($source_image) {
|
||||||
@ -1182,9 +1293,9 @@ class common
|
|||||||
return (imagepng($virtual_image, $dest));
|
return (imagepng($virtual_image, $dest));
|
||||||
case 'image/gif':
|
case 'image/gif':
|
||||||
return (imagegif($virtual_image, $dest));
|
return (imagegif($virtual_image, $dest));
|
||||||
case 'webp':
|
case 'image/webp':
|
||||||
return (imagewebp($virtual_image, $dest));
|
return (imagewebp($virtual_image, $dest));
|
||||||
case 'avif':
|
case 'image/avif':
|
||||||
return (imageavif($virtual_image, $dest));
|
return (imageavif($virtual_image, $dest));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1435,8 +1546,8 @@ class common
|
|||||||
foreach ($courses as $courseId => $value) {
|
foreach ($courses as $courseId => $value) {
|
||||||
// Affiche les espaces gérés par l'éditeur, les espaces où il participe et les espaces anonymes
|
// Affiche les espaces gérés par l'éditeur, les espaces où il participe et les espaces anonymes
|
||||||
if (
|
if (
|
||||||
// le membre est inscrit
|
// le membre est inscrit
|
||||||
( $this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) )
|
($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])))
|
||||||
// Il est l'auteur
|
// Il est l'auteur
|
||||||
|| $this->getUser('id') === $this->getData(['course', $courseId, 'author'])
|
|| $this->getUser('id') === $this->getData(['course', $courseId, 'author'])
|
||||||
// Le cours est ouvert
|
// Le cours est ouvert
|
||||||
@ -1450,7 +1561,7 @@ class common
|
|||||||
foreach ($courses as $courseId => $value) {
|
foreach ($courses as $courseId => $value) {
|
||||||
// Affiche les espaces du participant et les espaces anonymes
|
// Affiche les espaces du participant et les espaces anonymes
|
||||||
if (
|
if (
|
||||||
($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) )
|
($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])))
|
||||||
|| $this->getData(['course', $courseId, 'enrolment']) === self::COURSE_ENROLMENT_GUEST
|
|| $this->getData(['course', $courseId, 'enrolment']) === self::COURSE_ENROLMENT_GUEST
|
||||||
) {
|
) {
|
||||||
$filter[$courseId] = $courses[$courseId];
|
$filter[$courseId] = $courses[$courseId];
|
||||||
|
@ -10,7 +10,7 @@ if (
|
|||||||
) {
|
) {
|
||||||
// Supprime la variable path des profils, seul l'accès à l'espace et autorisé.
|
// Supprime la variable path des profils, seul l'accès à l'espace et autorisé.
|
||||||
foreach (['1', '2'] as $group) {
|
foreach (['1', '2'] as $group) {
|
||||||
foreach ( array_keys($this->getData(['profil', $group])) as $profil) {
|
foreach (array_keys($this->getData(['profil', $group])) as $profil) {
|
||||||
if (is_null($this->getData(['profil', $group, $profil, 'folder', 'path'])) === false) {
|
if (is_null($this->getData(['profil', $group, $profil, 'folder', 'path'])) === false) {
|
||||||
$path = $this->getData(['profil', $group, $profil, 'folder', 'path']);
|
$path = $this->getData(['profil', $group, $profil, 'folder', 'path']);
|
||||||
$this->setData(['profil', $group, $profil, 'folder', 'homePath', $path]);
|
$this->setData(['profil', $group, $profil, 'folder', 'homePath', $path]);
|
||||||
@ -20,4 +20,29 @@ if (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->setData(['core', 'dataVersion', 1700]);
|
$this->setData(['core', 'dataVersion', 1700]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
$this->getData(['core', 'dataVersion']) < 1800
|
||||||
|
) {
|
||||||
|
// Parcourir la structure pour écrire dans les fichiers CSV
|
||||||
|
foreach ($this->getData(['enrolment']) as $courseId => $users) {
|
||||||
|
$filename = self::DATA_DIR . $courseId . '/report.csv';
|
||||||
|
$fp = fopen($filename, 'w');
|
||||||
|
foreach ($users as $userId => $userData) {
|
||||||
|
$history = array_key_exists('history', $userData) ? $userData['history'] : null;
|
||||||
|
|
||||||
|
if (is_array($history)) {
|
||||||
|
foreach ($history as $pageId => $timestamps) {
|
||||||
|
foreach ($timestamps as $timestamp) {
|
||||||
|
fputcsv($fp, [$userId, $pageId, $timestamp], ';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->deleteData(['enrolment', $courseId, $userId, 'history']);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
$this->setData(['core', 'dataVersion', 1800]);
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html;">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<?php $layout->showMetaTitle(); ?>
|
<?php $layout->showMetaTitle(); ?>
|
||||||
<?php $layout->showMetaDescription(); ?>
|
<?php $layout->showMetaDescription(); ?>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html;">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<?php $layout->showMetaTitle(); ?>
|
<?php $layout->showMetaTitle(); ?>
|
||||||
<?php $layout->showMetaDescription(); ?>
|
<?php $layout->showMetaDescription(); ?>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr_FR">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr_FR">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html;">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="x-apple-disable-message-reformatting">
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
<html prefix="og: http://ogp.me/ns#" lang="fr_FR">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html;">
|
||||||
<meta meta="description=" content="ZwiiCMS le CMS multilingue sans base de données">
|
<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="generator" content="ZiiCMS https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -47,7 +47,7 @@
|
|||||||
if (
|
if (
|
||||||
$this->getData(['theme', 'menu', 'position']) === 'top'
|
$this->getData(['theme', 'menu', 'position']) === 'top'
|
||||||
and $this->getData(['theme', 'menu', 'fixed']) === true
|
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
|
and $this->getUser('group') > self::GROUP_MEMBER
|
||||||
) {
|
) {
|
||||||
echo '<nav id="navfixedconnected" >';
|
echo '<nav id="navfixedconnected" >';
|
||||||
|
@ -22,7 +22,7 @@ class config extends common
|
|||||||
'copyBackups' => self::GROUP_ADMIN,
|
'copyBackups' => self::GROUP_ADMIN,
|
||||||
'delBackups' => self::GROUP_ADMIN,
|
'delBackups' => self::GROUP_ADMIN,
|
||||||
'configMetaImage' => self::GROUP_ADMIN,
|
'configMetaImage' => self::GROUP_ADMIN,
|
||||||
'siteMap' => self::GROUP_ADMIN,
|
'sitemap' => self::GROUP_ADMIN,
|
||||||
'index' => self::GROUP_ADMIN,
|
'index' => self::GROUP_ADMIN,
|
||||||
'restore' => self::GROUP_ADMIN,
|
'restore' => self::GROUP_ADMIN,
|
||||||
'updateBaseUrl' => self::GROUP_ADMIN,
|
'updateBaseUrl' => self::GROUP_ADMIN,
|
||||||
@ -30,7 +30,8 @@ class config extends common
|
|||||||
'logReset' => self::GROUP_ADMIN,
|
'logReset' => self::GROUP_ADMIN,
|
||||||
'logDownload' => self::GROUP_ADMIN,
|
'logDownload' => self::GROUP_ADMIN,
|
||||||
'blacklistReset' => self::GROUP_ADMIN,
|
'blacklistReset' => self::GROUP_ADMIN,
|
||||||
'blacklistDownload' => self::GROUP_ADMIN
|
'blacklistDownload' => self::GROUP_ADMIN,
|
||||||
|
'register' => self::GROUP_ADMIN,
|
||||||
];
|
];
|
||||||
|
|
||||||
public static $timezones = [
|
public static $timezones = [
|
||||||
@ -213,7 +214,7 @@ class config extends common
|
|||||||
* Sitemap compressé et non compressé
|
* Sitemap compressé et non compressé
|
||||||
* Robots.txt
|
* Robots.txt
|
||||||
*/
|
*/
|
||||||
public function siteMap()
|
public function sitemap()
|
||||||
{
|
{
|
||||||
// La page n'existe pas
|
// La page n'existe pas
|
||||||
if (
|
if (
|
||||||
@ -490,7 +491,7 @@ class config extends common
|
|||||||
'cookiesFooterText' => $this->getInput('configLocaleCookiesFooterText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
|
'cookiesFooterText' => $this->getInput('configLocaleCookiesFooterText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
|
||||||
'buttonValidLabel' => $this->getInput('configLocaleCookiesButtonText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
|
'buttonValidLabel' => $this->getInput('configLocaleCookiesButtonText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
|
||||||
],
|
],
|
||||||
'social' => [
|
'social' => [
|
||||||
'facebookId' => $this->getInput('socialFacebookId'),
|
'facebookId' => $this->getInput('socialFacebookId'),
|
||||||
'linkedinId' => $this->getInput('socialLinkedinId'),
|
'linkedinId' => $this->getInput('socialLinkedinId'),
|
||||||
'instagramId' => $this->getInput('socialInstagramId'),
|
'instagramId' => $this->getInput('socialInstagramId'),
|
||||||
@ -556,7 +557,7 @@ class config extends common
|
|||||||
) {
|
) {
|
||||||
// Ajout des lignes dans le .htaccess
|
// Ajout des lignes dans le .htaccess
|
||||||
$fileContent = file_get_contents('.htaccess');
|
$fileContent = file_get_contents('.htaccess');
|
||||||
$rewriteData = PHP_EOL .
|
$rewriteData =
|
||||||
'# URL rewriting' . PHP_EOL .
|
'# URL rewriting' . PHP_EOL .
|
||||||
'<IfModule mod_rewrite.c>' . PHP_EOL .
|
'<IfModule mod_rewrite.c>' . PHP_EOL .
|
||||||
"\tRewriteEngine on" . PHP_EOL .
|
"\tRewriteEngine on" . PHP_EOL .
|
||||||
@ -565,7 +566,7 @@ class config extends common
|
|||||||
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
|
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
|
||||||
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
|
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
|
||||||
'</IfModule>' . PHP_EOL .
|
'</IfModule>' . PHP_EOL .
|
||||||
'# URL rewriting' . PHP_EOL;
|
'# URL rewriting';
|
||||||
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
|
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
'.htaccess',
|
'.htaccess',
|
||||||
@ -592,7 +593,7 @@ class config extends common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Générer robots.txt et sitemap
|
// Générer robots.txt et sitemap
|
||||||
$this->siteMap();
|
$this->sitemap();
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => helper::translate('Configuration'),
|
'title' => helper::translate('Configuration'),
|
||||||
@ -957,4 +958,40 @@ class config extends common
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fonction pour vérifier la présence du module de réécriture
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isModRewriteEnabled() {
|
||||||
|
// Check if Apache and mod_rewrite is loaded
|
||||||
|
if (function_exists('apache_get_modules')) {
|
||||||
|
$modules = apache_get_modules();
|
||||||
|
return in_array('mod_rewrite', $modules);
|
||||||
|
} else {
|
||||||
|
// Fallback if not using Apache or unable to detect modules
|
||||||
|
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),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
4
core/module/config/tool/.htaccess
Normal file
4
core/module/config/tool/.htaccess
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<Files "data.key">
|
||||||
|
Order Allow,Deny
|
||||||
|
Deny from all
|
||||||
|
</Files>
|
68
core/module/config/tool/autobackup.php
Normal file
68
core/module/config/tool/autobackup.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ce script PHP est conçu pour être appelé via une requête HTTP GET avec une clé spécifique pour déclencher la création d'une archive ZIP de sauvegarde.
|
||||||
|
|
||||||
|
Exemple d'appel dans une URL :
|
||||||
|
http://example.com/chemin/vers/autobackup.php?key=your_secret_key&filter=site
|
||||||
|
|
||||||
|
La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la création de l'archive soit autorisée. Si la clé est valide, le script parcourt le répertoire spécifié en fonction du paramètre "filter" et ajoute les fichiers à l'archive ZIP. Si la clé est invalide ou absente, le script renvoie une réponse avec le code d'erreur 401 Unauthorized.
|
||||||
|
|
||||||
|
Le paramètre "filter" en GET permet de spécifier le filtre à appliquer lors de la création de l'archive. Sa valeur peut être "file" ou "data". Si le paramètre n'est pas spécifié, le filtre est vide par défaut, ce qui signifie que tous les fichiers seront inclus dans l'archive.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Vérification de la clé
|
||||||
|
if (isset($_GET['key'])) {
|
||||||
|
$key = $_GET['key'];
|
||||||
|
$storedKey = file_get_contents('data.key');
|
||||||
|
if ($key !== $storedKey) {
|
||||||
|
http_response_code(401); // Clé invalide, renvoie une réponse avec le code d'erreur 401 Unauthorized
|
||||||
|
echo 'Clé incorrecte';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Définition du filtre par défaut
|
||||||
|
$filter = ['backup', 'tmp', 'i18n'];
|
||||||
|
|
||||||
|
// Tableau de correspondance entre les valeurs de "filter" et les répertoires à inclure
|
||||||
|
$filterDirectories = [
|
||||||
|
'file' => ['backup', 'tmp', 'file'],
|
||||||
|
'data' => ['backup', 'tmp', 'data'],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Vérification et traitement du paramètre "filter" en GET
|
||||||
|
if (isset($_GET['filter']) && isset($filterDirectories[$_GET['filter']])) {
|
||||||
|
$filter = $filterDirectories[$_GET['filter']];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création du ZIP
|
||||||
|
$fileName = date('Y-m-d-H-i-s', time()) . '-rolling-backup.zip';
|
||||||
|
$zip = new ZipArchive();
|
||||||
|
$zip->open('../../../../site/backup/' . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
||||||
|
$directory = '../../../../site';
|
||||||
|
$files = new RecursiveIteratorIterator(
|
||||||
|
new RecursiveCallbackFilterIterator(
|
||||||
|
new RecursiveDirectoryIterator(
|
||||||
|
$directory,
|
||||||
|
RecursiveDirectoryIterator::SKIP_DOTS
|
||||||
|
),
|
||||||
|
function ($fileInfo, $key, $iterator) use ($filter) {
|
||||||
|
return $fileInfo->isFile() || !in_array($fileInfo->getBaseName(), $filter);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
foreach ($files as $name => $file) {
|
||||||
|
if (!$file->isDir()) {
|
||||||
|
$filePath = $file->getRealPath();
|
||||||
|
$relativePath = substr($filePath, strlen(realpath($directory)) + 1);
|
||||||
|
$zip->addFile($filePath, $relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
http_response_code(201); // Création de l'archive réussie, renvoie une réponse avec le code 201 Created
|
||||||
|
echo 'Sauvegarde terminée';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
52
core/module/config/tool/cleanautobackup.php
Normal file
52
core/module/config/tool/cleanautobackup.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ce script PHP est conçu pour supprimer les fichiers ayant l'extension 'tar.gz' dans un répertoire de sauvegarde si leur dernière modification remonte à un certain nombre de jours spécifié via une requête HTTP GET.
|
||||||
|
|
||||||
|
Exemple d'appel dans une URL avec le nombre de jours spécifié :
|
||||||
|
http://example.com/chemin/vers/script.php?days=7&key=your_secret_key
|
||||||
|
|
||||||
|
Le script vérifie également la présence et la validité d'une clé spécifique pour déclencher son exécution. La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la suppression des fichiers soit autorisée. Si la clé est invalide ou absente, le script affiche un message d'erreur et termine son exécution.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Vérification de la clé
|
||||||
|
if (isset ($_GET['key'])) {
|
||||||
|
// Récupération de la clé fournie en GET
|
||||||
|
$key = $_GET['key'];
|
||||||
|
|
||||||
|
// Récupération de la clé stockée dans le fichier data.key
|
||||||
|
$storedKey = file_get_contents('data.key');
|
||||||
|
|
||||||
|
// Vérification de correspondance entre les clés
|
||||||
|
if ($key !== $storedKey) {
|
||||||
|
http_response_code(401);
|
||||||
|
echo 'Clé incorrecte';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupère le nombre de jours à partir de la variable GET 'days'
|
||||||
|
$days = isset ($_GET['days']) ? (int) $_GET['days'] : 1; // Par défaut à 1 si non spécifié
|
||||||
|
|
||||||
|
// Chemin vers le répertoire contenant les fichiers
|
||||||
|
$directory = '../../../../site/backup/'; // Remplacez par le chemin réel
|
||||||
|
|
||||||
|
// Convertit le nombre de jours en secondes
|
||||||
|
$timeLimit = strtotime("-$days days");
|
||||||
|
|
||||||
|
// Crée un nouvel objet DirectoryIterator
|
||||||
|
foreach (new DirectoryIterator($directory) as $file) {
|
||||||
|
// Vérifie si l'élément courant est un fichier et a l'extension 'tar.gz'
|
||||||
|
if ($file->isFile() && $file->getExtension() === 'tar.gz') {
|
||||||
|
// Vérifie si le fichier a été modifié avant la limite de temps
|
||||||
|
if ($file->getMTime() < $timeLimit) {
|
||||||
|
// Supprime le fichier
|
||||||
|
unlink($file->getRealPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Si la clé est manquante, affiche un message d'erreur et arrête l'exécution du script
|
||||||
|
http_response_code(201);
|
||||||
|
echo 'Sauvegarde terminée';
|
||||||
|
exit;
|
||||||
|
}
|
@ -66,11 +66,12 @@ $(document).ready(function () {
|
|||||||
$("#connectCaptchaStrong").prop("checked", false);
|
$("#connectCaptchaStrong").prop("checked", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var configLayout = getCookie("configLayout");
|
var configLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'config']);?>";
|
||||||
if (configLayout == null) {
|
// Non défini, valeur par défaut
|
||||||
configLayout = "locale";
|
if (configLayout == "") {
|
||||||
setCookie("configLayout", "locale");
|
configLayout = "setup";
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#localeContainer").hide();
|
$("#localeContainer").hide();
|
||||||
$("#socialContainer").hide();
|
$("#socialContainer").hide();
|
||||||
$("#connectContainer").hide();
|
$("#connectContainer").hide();
|
||||||
@ -168,7 +169,6 @@ $(document).ready(function () {
|
|||||||
$("#configSocialButton").removeClass("activeButton");
|
$("#configSocialButton").removeClass("activeButton");
|
||||||
$("#configConnectButton").removeClass("activeButton");
|
$("#configConnectButton").removeClass("activeButton");
|
||||||
$("#configNetworkButton").removeClass("activeButton");
|
$("#configNetworkButton").removeClass("activeButton");
|
||||||
setCookie("configLayout", "locale");
|
|
||||||
});
|
});
|
||||||
$("#configSetupButton").on("click", function () {
|
$("#configSetupButton").on("click", function () {
|
||||||
$("#localeContainer").hide();
|
$("#localeContainer").hide();
|
||||||
@ -181,7 +181,6 @@ $(document).ready(function () {
|
|||||||
$("#configSocialButton").removeClass("activeButton");
|
$("#configSocialButton").removeClass("activeButton");
|
||||||
$("#configConnectButton").removeClass("activeButton");
|
$("#configConnectButton").removeClass("activeButton");
|
||||||
$("#configNetworkButton").removeClass("activeButton");
|
$("#configNetworkButton").removeClass("activeButton");
|
||||||
setCookie("configLayout", "setup");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#configSocialButton").on("click", function () {
|
$("#configSocialButton").on("click", function () {
|
||||||
@ -195,7 +194,6 @@ $(document).ready(function () {
|
|||||||
$("#configSocialButton").addClass("activeButton");
|
$("#configSocialButton").addClass("activeButton");
|
||||||
$("#configConnectButton").removeClass("activeButton");
|
$("#configConnectButton").removeClass("activeButton");
|
||||||
$("#configNetworkButton").removeClass("activeButton");
|
$("#configNetworkButton").removeClass("activeButton");
|
||||||
setCookie("configLayout", "social");
|
|
||||||
});
|
});
|
||||||
$("#configConnectButton").on("click", function () {
|
$("#configConnectButton").on("click", function () {
|
||||||
$("#setupContainer").hide();
|
$("#setupContainer").hide();
|
||||||
@ -208,7 +206,6 @@ $(document).ready(function () {
|
|||||||
$("#configSocialButton").removeClass("activeButton");
|
$("#configSocialButton").removeClass("activeButton");
|
||||||
$("#configConnectButton").addClass("activeButton");
|
$("#configConnectButton").addClass("activeButton");
|
||||||
$("#configNetworkButton").removeClass("activeButton");
|
$("#configNetworkButton").removeClass("activeButton");
|
||||||
setCookie("configLayout", "connect");
|
|
||||||
});
|
});
|
||||||
$("#configNetworkButton").on("click", function () {
|
$("#configNetworkButton").on("click", function () {
|
||||||
$("#setupContainer").hide();
|
$("#setupContainer").hide();
|
||||||
@ -221,7 +218,6 @@ $(document).ready(function () {
|
|||||||
$("#configSocialButton").removeClass("activeButton");
|
$("#configSocialButton").removeClass("activeButton");
|
||||||
$("#configConnectButton").removeClass("activeButton");
|
$("#configConnectButton").removeClass("activeButton");
|
||||||
$("#configNetworkButton").addClass("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
|
// Define function to capitalize the first letter of a string
|
||||||
function capitalizeFirstLetter(string) {
|
function capitalizeFirstLetter(string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
@ -7,44 +7,35 @@
|
|||||||
'value' => template::ico('home')
|
'value' => template::ico('home')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2 offset9">
|
||||||
<?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">
|
|
||||||
<?php echo template::submit('Submit'); ?>
|
<?php echo template::submit('Submit'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<?php echo template::button('configLocaleButton', [
|
<?php echo template::button('configLocaleButton', [
|
||||||
'value' => 'Identité - Etiquettes',
|
'value' => 'Identité - Étiquettes',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab'
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php echo template::button('configSetupButton', [
|
<?php echo template::button('configSetupButton', [
|
||||||
'value' => 'Configuration - Outils',
|
'value' => 'Configuration',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'config/register/setup'
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php echo template::button('configSocialButton', [
|
<?php echo template::button('configSocialButton', [
|
||||||
'value' => 'Réseaux sociaux',
|
'value' => 'Référencement',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'config/register/social'
|
||||||
]); ?>
|
]); ?>
|
||||||
|
|
||||||
<?php echo template::button('configConnectButton', [
|
<?php echo template::button('configConnectButton', [
|
||||||
'value' => 'Sécurité',
|
'value' => 'Connexion',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'config/register/connect'
|
||||||
]); ?>
|
]); ?>
|
||||||
|
|
||||||
<?php echo template::button('configNetworkButton', [
|
<?php echo template::button('configNetworkButton', [
|
||||||
'value' => 'Réseau',
|
'value' => 'Réseau',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'config/register/network'
|
||||||
]); ?>
|
]); ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php include('core/module/config/view/locale/locale.php') ?>
|
<?php include('core/module/config/view/locale/locale.php') ?>
|
||||||
<?php include('core/module/config/view/setup/setup.php') ?>
|
<?php include('core/module/config/view/setup/setup.php') ?>
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Étiquettes des pages spéciales'); ?>
|
<?php echo helper::translate('Étiquettes des pages spéciales'); ?>
|
||||||
<!--<span id="labelHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
|
<!--<span id="labelHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
|
||||||
<a href="https://doc.zwiicms.fr/etiquettes-des-pages-speciales" target="_blank">
|
<a href="https://doc.zwiicms.fr/Étiquettes-des-pages-speciales" target="_blank">
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
||||||
</a>
|
</a>
|
||||||
</span>-->
|
</span>-->
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col2 offset8">
|
<div class="col2 offset9">
|
||||||
<?php echo template::submit('configManageSubmit', [
|
<?php echo template::submit('configManageSubmit', [
|
||||||
'value' => 'Valider',
|
'value' => 'Valider',
|
||||||
'ico' => 'check'
|
'ico' => 'check'
|
||||||
|
@ -3,12 +3,6 @@
|
|||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4><?php echo helper::translate('Paramètres'); ?>
|
<h4><?php echo helper::translate('Paramètres'); ?>
|
||||||
<!--<span id="setupHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/parametres" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']);
|
|
||||||
?>
|
|
||||||
</a>-->
|
|
||||||
</span>
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col4">
|
<div class="col4">
|
||||||
@ -17,7 +11,8 @@
|
|||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
||||||
'label' => 'Favicon',
|
'label' => 'Favicon',
|
||||||
'value' => $this->getData(['config', 'favicon'])
|
'value' => $this->getData(['config', 'favicon']),
|
||||||
|
'folder' => $this->getData(['config', 'favicon']) ? dirname($this->getData(['config', 'favicon'])) : ''
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col4">
|
<div class="col4">
|
||||||
@ -26,7 +21,8 @@
|
|||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'help' => 'Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
'help' => 'Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
||||||
'label' => 'Favicon thème sombre',
|
'label' => 'Favicon thème sombre',
|
||||||
'value' => $this->getData(['config', 'faviconDark'])
|
'value' => $this->getData(['config', 'faviconDark']),
|
||||||
|
'folder' => $this->getData(['config', 'faviconDark']) ? dirname($this->getData(['config', 'faviconDark'])) : ''
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col4">
|
<div class="col4">
|
||||||
@ -47,8 +43,8 @@
|
|||||||
<div class="col6">
|
<div class="col6">
|
||||||
<?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
|
<?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
|
||||||
'checked' => helper::checkRewrite(),
|
'checked' => helper::checkRewrite(),
|
||||||
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
|
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
|
||||||
'disabled' => stripos($_SERVER["SERVER_SOFTWARE"], 'nginx')
|
'disabled' => helper::checkServerSoftware() === false and $module->isModRewriteEnabled()
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -59,12 +55,6 @@
|
|||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4><?php echo helper::translate('Mise à jour automatisée'); ?>
|
<h4><?php echo helper::translate('Mise à jour automatisée'); ?>
|
||||||
<!--<span id="updateHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/mise-a-jour" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']);
|
|
||||||
?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col6">
|
||||||
@ -90,8 +80,8 @@
|
|||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col3 offset1 verticalAlignBottom">
|
<div class="col3 offset1 verticalAlignBottom">
|
||||||
<pre>Version installée : <strong><?php echo common::ZWII_VERSION ; ?></strong></pre>
|
<pre>Version installée : <strong><?php echo common::ZWII_VERSION; ?></strong></pre>
|
||||||
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) ; ?></strong></pre>
|
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL); ?></strong></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="col3 offset2 verticalAlignBottom">
|
<div class="col3 offset2 verticalAlignBottom">
|
||||||
<?php echo template::button('configUpdateForced', [
|
<?php echo template::button('configUpdateForced', [
|
||||||
@ -109,12 +99,6 @@
|
|||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4><?php echo helper::translate('Maintenance'); ?>
|
<h4><?php echo helper::translate('Maintenance'); ?>
|
||||||
<!--<span id="maintenanceHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/mode-maintenance" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']);
|
|
||||||
?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col6">
|
||||||
@ -169,12 +153,6 @@
|
|||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4><?php echo helper::translate('Scripts externes'); ?>
|
<h4><?php echo helper::translate('Scripts externes'); ?>
|
||||||
<!--<span id="specialeHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/scripts-externes" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']);
|
|
||||||
?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col4 offset1 verticalAlignBottom">
|
<div class="col4 offset1 verticalAlignBottom">
|
||||||
@ -198,13 +176,21 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a href="https://forum.zwiicms.fr" target="_blank">Forum</a>
|
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a
|
||||||
|
href="https://forum.zwiicms.fr" target="_blank">Forum</a>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row textAlignCenter">
|
<div class="row textAlignCenter">
|
||||||
<div class="col12">
|
<div class="col12">
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img
|
||||||
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Pas de Modification 4.0 International.</a></p>
|
alt="Licence Creative Commons" style="border-width:0"
|
||||||
<p>Pour voir une copie de cette licence, visitez http://creativecommons.org/licenses/by-nc-nd/4.0/ ou écrivez à Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.</p>
|
src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
|
||||||
|
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license"
|
||||||
|
href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons
|
||||||
|
Attribution - Pas d'Utilisation Commerciale - Pas de Modification 4.0
|
||||||
|
International.</a></p>
|
||||||
|
<p>Pour voir une copie de cette licence, visitez
|
||||||
|
http://creativecommons.org/licenses/by-nc-nd/4.0/ ou écrivez à Creative Commons, PO Box
|
||||||
|
1866, Mountain View, CA 94042, USA.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Capture d\'écran Open Graph'); ?>
|
<?php echo helper::translate('Capture d\'écran Open Graph'); ?>
|
||||||
<!--<span id="specialeHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col6">
|
||||||
@ -18,29 +13,30 @@
|
|||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'label' => 'Image Open Graph',
|
'label' => 'Image Open Graph',
|
||||||
'value' => $this->getData(['config', 'seo', 'openGraphImage']),
|
'value' => $this->getData(['config', 'seo', 'openGraphImage']),
|
||||||
|
'folder' => $this->getData(['config', 'seo', 'openGraphImage']) ? dirname($this->getData(['config', 'seo', 'openGraphImage'])) : '',
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
'help' => sprintf('%s : JPG - PNG<br />', helper::translate('Format')) .
|
'help' => sprintf('%s : JPG - PNG<br />', helper::translate('Format')) .
|
||||||
sprintf('%s : 1200 x 630 pixels<br />', helper::translate('Dimensions minimales')) .
|
sprintf('%s : 1200 x 630 pixels<br />', helper::translate('Dimensions minimales')) .
|
||||||
sprintf('%s : 1.91:1<br />', helper::translate('Ratio')) .
|
sprintf('%s : 1.91:1<br />', helper::translate('Ratio')) .
|
||||||
sprintf('%s : %s, %s<br />', helper::translate('Taille maximale du fichier'), helper::translate('5 Mo pour les images JPEG'), helper::translate('1 Mo pour les images PNG'))
|
sprintf('%s : %s, %s<br />', helper::translate('Taille maximale du fichier'), helper::translate('5 Mo pour les images JPEG'), helper::translate('1 Mo pour les images PNG'))
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col10 textAlignCenter">
|
<div class="col10 textAlignCenter">
|
||||||
<?php if( !empty($module::$imageOpenGraph['type']) ): ?>
|
<?php if (!empty($module::$imageOpenGraph['type'])): ?>
|
||||||
<p>
|
<p>
|
||||||
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
|
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<?php echo sprintf('%s : <span id="screenWide">%s</span> x <span id="screenHeight">%s</span> pixels', helper::translate('Dimensions minimales'), $module::$imageOpenGraph['wide'], $module::$imageOpenGraph['height'] ); ?>
|
<?php echo sprintf('%s : <span id="screenWide">%s</span> x <span id="screenHeight">%s</span> pixels', helper::translate('Dimensions minimales'), $module::$imageOpenGraph['wide'], $module::$imageOpenGraph['height']); ?>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<?php echo sprintf('%s : <span id="screenRatio">%s</span><span id="screenFract">:1</span>' , helper::translate('Ratio'), round($module::$imageOpenGraph['ratio'], 2)); ?>
|
<?php echo sprintf('%s : <span id="screenRatio">%s</span><span id="screenFract">:1</span>', helper::translate('Ratio'), round($module::$imageOpenGraph['ratio'], 2)); ?>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<?php echo sprintf('%s : <span id="screenWeight">%s</span>', helper::translate('Poids'), $module::$imageOpenGraph['size']); ?>
|
<?php echo sprintf('%s : <span id="screenWeight">%s</span>', helper::translate('Poids'), $module::$imageOpenGraph['size']); ?>
|
||||||
</p>
|
</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -48,10 +44,10 @@
|
|||||||
<div class="col6">
|
<div class="col6">
|
||||||
<?php if (
|
<?php if (
|
||||||
$this->getData(['config', 'seo', 'openGraphImage']) &&
|
$this->getData(['config', 'seo', 'openGraphImage']) &&
|
||||||
file_exists(self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']))
|
file_exists(self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']))
|
||||||
): ?>
|
): ?>
|
||||||
<img
|
<img
|
||||||
src="<?php echo self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']); ?>" />
|
src="<?php echo self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']); ?>" />
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,12 +80,6 @@
|
|||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Réseaux sociaux'); ?>
|
|
||||||
<!--<span id="specialeHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/reseaux-sociaux" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col3">
|
<div class="col3">
|
||||||
|
@ -26,12 +26,13 @@ class course extends common
|
|||||||
'users' => self::GROUP_EDITOR, // fait
|
'users' => self::GROUP_EDITOR, // fait
|
||||||
'usersAdd' => self::GROUP_EDITOR, //Fait
|
'usersAdd' => self::GROUP_EDITOR, //Fait
|
||||||
'usersDelete' => self::GROUP_EDITOR, //Fait
|
'usersDelete' => self::GROUP_EDITOR, //Fait
|
||||||
'usersHistoryExport' => self::GROUP_EDITOR, //fait
|
'usersReportExport' => self::GROUP_EDITOR, //fait
|
||||||
'userDelete' => self::GROUP_EDITOR, //Fait
|
'userDelete' => self::GROUP_EDITOR, //Fait
|
||||||
'userHistory' => self::GROUP_EDITOR, //Fait
|
'userReport' => self::GROUP_EDITOR, //Fait
|
||||||
'userHistoryExport' => self::GROUP_EDITOR, //Fait
|
'userReportExport' => self::GROUP_EDITOR, //Fait
|
||||||
'backup' => self::GROUP_EDITOR, // Fait
|
'backup' => self::GROUP_EDITOR, // Fait
|
||||||
'restore' => self::GROUP_EDITOR, //Fait
|
'restore' => self::GROUP_EDITOR, //Fait
|
||||||
|
'reset' => self::GROUP_EDITOR,
|
||||||
'clone' => self::GROUP_ADMIN,
|
'clone' => self::GROUP_ADMIN,
|
||||||
'add' => self::GROUP_ADMIN,
|
'add' => self::GROUP_ADMIN,
|
||||||
'delete' => self::GROUP_ADMIN,
|
'delete' => self::GROUP_ADMIN,
|
||||||
@ -39,6 +40,7 @@ class course extends common
|
|||||||
'categoryAdd' => self::GROUP_ADMIN,
|
'categoryAdd' => self::GROUP_ADMIN,
|
||||||
'categoryEdit' => self::GROUP_ADMIN,
|
'categoryEdit' => self::GROUP_ADMIN,
|
||||||
'categoryDelete' => self::GROUP_ADMIN,
|
'categoryDelete' => self::GROUP_ADMIN,
|
||||||
|
'export' => self::GROUP_ADMIN,
|
||||||
];
|
];
|
||||||
|
|
||||||
public static $courseAccess = [
|
public static $courseAccess = [
|
||||||
@ -74,7 +76,7 @@ class course extends common
|
|||||||
public static $pagesList = ['accueil' => 'Accueil'];
|
public static $pagesList = ['accueil' => 'Accueil'];
|
||||||
|
|
||||||
|
|
||||||
public static $userHistory = [];
|
public static $userReport = [];
|
||||||
|
|
||||||
public static $userGraph = [];
|
public static $userGraph = [];
|
||||||
|
|
||||||
@ -85,6 +87,9 @@ class course extends common
|
|||||||
// Tableau à transmettre à la fvue
|
// Tableau à transmettre à la fvue
|
||||||
self::$courses = array();
|
self::$courses = array();
|
||||||
|
|
||||||
|
// Pointer RFM sur le dossier de l'espace
|
||||||
|
self::$siteContent = 'home';
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->getUser('id')
|
$this->getUser('id')
|
||||||
&& $this->getUser('group')
|
&& $this->getUser('group')
|
||||||
@ -104,19 +109,26 @@ class course extends common
|
|||||||
? sprintf('%s %s', $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'firstname']), $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'lastname']))
|
? sprintf('%s %s', $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'firstname']), $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'lastname']))
|
||||||
: '';
|
: '';
|
||||||
$categorieUrl = helper::baseUrl() . 'course/swap/' . $courseId;
|
$categorieUrl = helper::baseUrl() . 'course/swap/' . $courseId;
|
||||||
$info = sprintf(' <a href="%s" target="_blank">%s</a><br />Auteur : %s<br />Id : %s<br />', $categorieUrl, $this->getData(['course', $courseId, 'title']), $author, $courseId,);
|
$info = sprintf(' <a href="%s">%s</a><br />Auteur : %s<br />Id : %s<br />', $categorieUrl, $this->getData(['course', $courseId, 'title']), $author, $courseId, );
|
||||||
$enrolment = sprintf(
|
$enrolment = sprintf(
|
||||||
'Accès : %s<br />Inscription : %s<br />',
|
'Accès : %s<br />Inscription : %s<br />',
|
||||||
self::$courseAccess[$this->getData(['course', $courseId, 'access'])],
|
self::$courseAccess[$this->getData(['course', $courseId, 'access'])],
|
||||||
self::$courseEnrolment[$this->getData(['course', $courseId, 'enrolment'])]
|
self::$courseEnrolment[$this->getData(['course', $courseId, 'enrolment'])]
|
||||||
);
|
);
|
||||||
|
if ($this->getUser('permission', 'course', 'users') === true) {
|
||||||
|
$users = template::button('categoryUser' . $this->getUrl(2), [
|
||||||
|
'href' => helper::baseUrl() . 'course/users/' . $courseId,
|
||||||
|
'value' => template::ico('users'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
self::$courses[] = [
|
self::$courses[] = [
|
||||||
$info,
|
$info,
|
||||||
$this->getData(['course', $courseId, 'description']),
|
$this->getData(['course', $courseId, 'description']),
|
||||||
$enrolment,
|
$enrolment,
|
||||||
|
$users,
|
||||||
template::button('categoryUser' . $courseId, [
|
template::button('categoryUser' . $courseId, [
|
||||||
'href' => helper::baseUrl() . 'course/manage/' . $courseId,
|
'href' => helper::baseUrl() . 'course/manage/' . $courseId,
|
||||||
'value' => template::ico('eye'),
|
'value' => template::ico('sliders'),
|
||||||
'help' => 'Gérer'
|
'help' => 'Gérer'
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
@ -165,6 +177,11 @@ class course extends common
|
|||||||
$this->initData('module', $courseId);
|
$this->initData('module', $courseId);
|
||||||
$this->initData('theme', $courseId);
|
$this->initData('theme', $courseId);
|
||||||
|
|
||||||
|
// Pointer RFM sur le dossier de l'espace
|
||||||
|
self::$siteContent = $courseId;
|
||||||
|
// Ordonne les pages par position
|
||||||
|
$this->buildHierarchy();
|
||||||
|
|
||||||
// BDD des inscrits
|
// BDD des inscrits
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'enrolment',
|
'enrolment',
|
||||||
@ -295,14 +312,24 @@ class course extends common
|
|||||||
self::$courseCategories = $this->getData(['category']);
|
self::$courseCategories = $this->getData(['category']);
|
||||||
|
|
||||||
// Liste des pages disponibles
|
// Liste des pages disponibles
|
||||||
$this->initDB('page', $this->getUrl(2));
|
$this->initDB('page', $courseId);
|
||||||
|
|
||||||
|
// Pointer RFM sur le dossier de l'espace
|
||||||
|
self::$siteContent = $courseId;
|
||||||
|
|
||||||
|
// Ordonne les pages par position
|
||||||
|
$this->buildHierarchy();
|
||||||
|
|
||||||
|
// Données pour le formulaire
|
||||||
self::$pagesList = $this->getData(['page']);
|
self::$pagesList = $this->getData(['page']);
|
||||||
foreach (self::$pagesList as $page => $pageId) {
|
|
||||||
|
// Exclure les barres et les pages désactivées
|
||||||
|
foreach (self::$pagesList as $pageId => $page) {
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $page, 'block']) === 'bar' ||
|
$page['block'] === 'bar' ||
|
||||||
$this->getData(['page', $page, 'disable']) === true
|
$page['disable'] === true
|
||||||
) {
|
) {
|
||||||
unset(self::$pagesList[$page]);
|
unset(self::$pagesList[$pageId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,14 +371,24 @@ class course extends common
|
|||||||
self::$courseCategories = $this->getData(['category']);
|
self::$courseCategories = $this->getData(['category']);
|
||||||
|
|
||||||
// Liste des pages disponibles
|
// Liste des pages disponibles
|
||||||
$this->initDB('page', $this->getUrl(2));
|
$this->initDB('page', $courseId);
|
||||||
|
|
||||||
|
// Pointer RFM sur le dossier de l'espace
|
||||||
|
self::$siteContent = $courseId;
|
||||||
|
|
||||||
|
// Ordonne les pages par position
|
||||||
|
$this->buildHierarchy();
|
||||||
|
|
||||||
|
// Données pour le formulaire
|
||||||
self::$pagesList = $this->getData(['page']);
|
self::$pagesList = $this->getData(['page']);
|
||||||
foreach (self::$pagesList as $page => $pageId) {
|
|
||||||
|
// Exclure les barres et les pages désactivées
|
||||||
|
foreach (self::$pagesList as $pageId => $page) {
|
||||||
if (
|
if (
|
||||||
$this->getData(['page', $page, 'block']) === 'bar' ||
|
$page['block'] === 'bar' ||
|
||||||
$this->getData(['page', $page, 'disable']) === true
|
$page['disable'] === true
|
||||||
) {
|
) {
|
||||||
unset(self::$pagesList[$page]);
|
unset(self::$pagesList[$pageId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +402,7 @@ class course extends common
|
|||||||
/**
|
/**
|
||||||
* Duplique un cours et l'affiche dans l'éditeur
|
* Duplique un cours et l'affiche dans l'éditeur
|
||||||
*/
|
*/
|
||||||
public function clone ()
|
public function clone()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Cours à dupliquer
|
// Cours à dupliquer
|
||||||
@ -632,36 +669,19 @@ class course extends common
|
|||||||
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
||||||
$sumPages = 0;
|
$sumPages = 0;
|
||||||
$pages = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
$pages = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
||||||
$pages = $pages['page'];
|
$sumPages = $this->countPages($pages['page']);
|
||||||
foreach ($pages as $pageId => $pageData) {
|
|
||||||
if ($pageData['position'] > 0) {
|
|
||||||
$sumPages++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Liste des inscrits dans le contenu sélectionné.
|
// Liste des inscrits dans le contenu sélectionné.
|
||||||
$users = $this->getData(['enrolment', $courseId]);
|
$users = $this->getData(['enrolment', $courseId]);
|
||||||
|
|
||||||
|
// Obtient les statistiques de l'ensemble de la cohorte
|
||||||
|
$reports = $this->getReport($courseId);
|
||||||
|
|
||||||
if (is_array($users)) {
|
if (is_array($users)) {
|
||||||
// Tri du tableau par défaut par $userId
|
// Tri du tableau par défaut par $userId
|
||||||
ksort($users);
|
ksort($users);
|
||||||
foreach ($users as $userId => $userValue) {
|
foreach ($users as $userId => $userValue) {
|
||||||
|
|
||||||
// Date et heure de la dernière page vue
|
|
||||||
// Compatibilité anciennes versions
|
|
||||||
if (
|
|
||||||
$this->getData(['enrolment', $courseId, $userId, 'lastPageView']) === null
|
|
||||||
or $this->getData(['enrolment', $courseId, $userId, 'datePageView']) === null
|
|
||||||
) {
|
|
||||||
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, 'datePageView', $maxTime]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Compte les rôles valides
|
// Compte les rôles valides
|
||||||
if (isset($profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])])) {
|
if (isset($profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])])) {
|
||||||
$profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])]++;
|
$profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])]++;
|
||||||
@ -694,28 +714,36 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Progression
|
// Progression
|
||||||
$viewPages = $this->getData(['enrolment', $courseId, $userId, 'history']) !== null ?
|
$viewPages = array_key_exists($userId, $reports) ?
|
||||||
count(array_keys($this->getData(['enrolment', $courseId, $userId, 'history']))) :
|
count($reports[$userId]) :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
// Construction du tableau
|
// Construction du tableau
|
||||||
self::$courseUsers[] = [
|
self::$courseUsers[] = [
|
||||||
//$userId,
|
//$userId,
|
||||||
$this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']),
|
$this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']),
|
||||||
isset($pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])]['title'])
|
array_key_exists('lastPageView', $userValue) && isset($pages[$userValue['lastPageView']]['title'])
|
||||||
? $pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])]['title']
|
? $pages[$userValue['lastPageView']]['title']
|
||||||
: '',
|
: '',
|
||||||
$this->getData(['enrolment', $courseId, $userId, 'datePageView'])
|
array_key_exists('lastPageView', $userValue)
|
||||||
? helper::dateUTF8('%d/%m/%Y', $this->getData(['enrolment', $courseId, $userId, 'datePageView']))
|
? helper::dateUTF8('%d/%m/%Y', $userValue['datePageView'])
|
||||||
: '',
|
: '',
|
||||||
$this->getData(['enrolment', $courseId, $userId, 'datePageView'])
|
array_key_exists('datePageView', $userValue)
|
||||||
? helper::dateUTF8('%H:%M', $this->getData(['enrolment', $courseId, $userId, 'datePageView']))
|
? helper::dateUTF8('%H:%M', $userValue['datePageView'])
|
||||||
: '',
|
: '',
|
||||||
$this->getData(['user', $userId, 'tags']),
|
$this->getData(['user', $userId, 'tags']),
|
||||||
template::button('userHistory' . $userId, [
|
template::button('userReport' . $userId, [
|
||||||
'href' => helper::baseUrl() . 'course/userHistory/' . $courseId . '/' . $userId,
|
'href' => helper::baseUrl() . 'course/userReport/' . $courseId . '/' . $userId,
|
||||||
'value' => !empty($userValue['history']) ? min(round(($viewPages * 100) / $sumPages, 1), 100) . ' %' : '0%',
|
/** La lecture de la progression s'effectue selon la nouvelle méthode (progression dans la base des enrolements)
|
||||||
'disable' => empty($userValue['history'])
|
* Soit avec l'ancienne méthode qui consiste à recalculer la progression.
|
||||||
|
* TRANSITOIRE A SUPPRIMER EN FIN D'ANNEE
|
||||||
|
**/
|
||||||
|
'value' => array_key_exists('progress', $userValue)
|
||||||
|
? $userValue['progress']
|
||||||
|
: ($viewPages ? min(round(($viewPages * 100) / $sumPages, 1), 100) . ' %' : '0%'),
|
||||||
|
'disable' => empty($userValue['datePageView']),
|
||||||
|
//'value' => $viewPages ? min(round(($viewPages * 100) / $sumPages, 1), 100) . ' %' : '0%',
|
||||||
|
//'disable' => empty($viewPages)
|
||||||
]),
|
]),
|
||||||
template::button('userDelete' . $userId, [
|
template::button('userDelete' . $userId, [
|
||||||
'class' => 'userDelete buttonRed',
|
'class' => 'userDelete buttonRed',
|
||||||
@ -773,9 +801,11 @@ class course extends common
|
|||||||
$this->getData(['user', $keyPost]) !== null
|
$this->getData(['user', $keyPost]) !== null
|
||||||
&& $this->getData(['enrolment', $courseId, $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
|
// Liste des groupes et des profils
|
||||||
@ -915,6 +945,7 @@ class course extends common
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Désinscription de tous les utilisateurs
|
* Désinscription de tous les utilisateurs
|
||||||
|
* Les désinscriptions ne suppriment pas les historiques
|
||||||
*/
|
*/
|
||||||
public function usersDelete()
|
public function usersDelete()
|
||||||
{
|
{
|
||||||
@ -1050,6 +1081,47 @@ class course extends common
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Désincription de tous les utilisateurs hors les éditeurs
|
||||||
|
* Effacement des historiques
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Contenu sélectionné
|
||||||
|
$courseId = $this->getUrl(2);
|
||||||
|
|
||||||
|
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
|
||||||
|
if (
|
||||||
|
$this->permissionControl(__FUNCTION__, $courseId) === false
|
||||||
|
) {
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'access' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Active l'accueil
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = 'home';
|
||||||
|
|
||||||
|
// Efface les inscriptions
|
||||||
|
$success = $this->setData(['enrolment', $courseId, []]);
|
||||||
|
|
||||||
|
// Efface les rapports
|
||||||
|
if (file_exists(self::DATA_DIR . $courseId . '/report.csv')) {
|
||||||
|
unlink(self::DATA_DIR . $courseId . '/report.csv');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'redirect' => helper::baseUrl() . 'course',
|
||||||
|
'notification' => helper::translate('Espace réinitialisé'),
|
||||||
|
'state' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Traitement du changement de langue
|
* Traitement du changement de langue
|
||||||
*/
|
*/
|
||||||
@ -1079,19 +1151,14 @@ class course extends common
|
|||||||
elseif (
|
elseif (
|
||||||
$this->courseIsUserEnroled($courseId)
|
$this->courseIsUserEnroled($courseId)
|
||||||
&& $this->courseIsAvailable($courseId)
|
&& $this->courseIsAvailable($courseId)
|
||||||
) {
|
) {
|
||||||
// Récupérer la dernière page visitée par cet utilisateur si elle existe
|
// Récupérer la dernière page visitée par cet utilisateur si elle existe
|
||||||
$redirect = ( $this->getData(['enrolment', $courseId, $userId, 'lastPageView']) !== null
|
$redirect = ($this->getData(['enrolment', $courseId, $userId, 'lastPageView']) !== null
|
||||||
&& array_key_exists($this->getData(['enrolment', $courseId, $userId, 'lastPageView']), $pages)
|
&& array_key_exists($this->getData(['enrolment', $courseId, $userId, 'lastPageView']), $pages)
|
||||||
)
|
)
|
||||||
? helper::baseUrl() . $this->getData(['enrolment', $courseId, $userId, 'lastPageView'])
|
? helper::baseUrl() . $this->getData(['enrolment', $courseId, $userId, 'lastPageView'])
|
||||||
: helper::baseUrl();
|
: 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) {
|
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);
|
$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);
|
$message .= sprintf(helper::translate('Ce contenu ferme le %s'), $to);
|
||||||
@ -1164,7 +1231,7 @@ class course extends common
|
|||||||
/**
|
/**
|
||||||
* Liste les pages consultées par un utilisateur
|
* Liste les pages consultées par un utilisateur
|
||||||
*/
|
*/
|
||||||
public function userHistory()
|
public function userReport()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Espace sélectionné
|
// Espace sélectionné
|
||||||
@ -1181,17 +1248,18 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userId = $this->getUrl(3);
|
$userId = $this->getUrl(3);
|
||||||
$h = $this->getData(['enrolment', $courseId, $userId, 'history']);
|
$h = $this->getReport($courseId, $userId);
|
||||||
|
$h = $h[$userId];
|
||||||
|
|
||||||
// Inversion des clés et des valeurs
|
// Inversion des clés et des valeurs
|
||||||
$history = array();
|
$report = array();
|
||||||
foreach ($h as $key => $values) {
|
foreach ($h as $key => $values) {
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$history[$value] = $key;
|
$report[$value] = $key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($history);
|
ksort($report);
|
||||||
|
|
||||||
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
||||||
$p = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
$p = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
||||||
@ -1207,11 +1275,11 @@ class course extends common
|
|||||||
$topTime = 0;
|
$topTime = 0;
|
||||||
$lastView = 0;
|
$lastView = 0;
|
||||||
|
|
||||||
foreach ($history as $time => $pageId) {
|
foreach ($report as $time => $pageId) {
|
||||||
if (isset($pages[$pageId]['title'])) {
|
if (isset($pages[$pageId]['title'])) {
|
||||||
$lastView = ($lastView === 0) ? $time : $lastView;
|
$lastView = ($lastView === 0) ? $time : $lastView;
|
||||||
$diff = $time - $lastView;
|
$diff = $time - $lastView;
|
||||||
self::$userHistory[] = [
|
self::$userReport[] = [
|
||||||
html_entity_decode($pages[$pageId]['title']),
|
html_entity_decode($pages[$pageId]['title']),
|
||||||
$time,
|
$time,
|
||||||
($diff < 1800) ? sprintf("%d' %d''", floor($diff / 60), $diff % 60) : "Non significatif",
|
($diff < 1800) ? sprintf("%d' %d''", floor($diff / 60), $diff % 60) : "Non significatif",
|
||||||
@ -1230,16 +1298,16 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Décale les temps de consultation
|
// Décale les temps de consultation
|
||||||
for ($i = 0; $i < count(self::$userHistory) - 1; $i++) {
|
for ($i = 0; $i < count(self::$userReport) - 1; $i++) {
|
||||||
self::$userHistory[$i][2] = self::$userHistory[$i + 1][2];
|
self::$userReport[$i][2] = self::$userReport[$i + 1][2];
|
||||||
}
|
}
|
||||||
// Décale les temps de consultation
|
// Décale les temps de consultation
|
||||||
for ($i = 0; $i < count(self::$userGraph) - 1; $i++) {
|
for ($i = 0; $i < count(self::$userGraph) - 1; $i++) {
|
||||||
self::$userHistory[$i][1] = self::$userHistory[$i + 1][1];
|
self::$userReport[$i][1] = self::$userReport[$i + 1][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formate le timestamp
|
// Formate le timestamp
|
||||||
array_walk(self::$userHistory, function (&$item) {
|
array_walk(self::$userReport, function (&$item) {
|
||||||
$item[1] = helper::dateUTF8('%d/%m/%Y %H:%M:%S', $item[1]);
|
$item[1] = helper::dateUTF8('%d/%m/%Y %H:%M:%S', $item[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1257,7 +1325,7 @@ class course extends common
|
|||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => helper::translate('Historique ') . $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']),
|
'title' => helper::translate('Historique ') . $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']),
|
||||||
'view' => 'userHistory',
|
'view' => 'userReport',
|
||||||
'vendor' => [
|
'vendor' => [
|
||||||
"plotly"
|
"plotly"
|
||||||
]
|
]
|
||||||
@ -1265,7 +1333,7 @@ class course extends common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function usersHistoryExport()
|
public function usersReportExport()
|
||||||
{
|
{
|
||||||
|
|
||||||
$courseId = $this->getUrl(2);
|
$courseId = $this->getUrl(2);
|
||||||
@ -1281,7 +1349,7 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
self::$courseUsers = [
|
self::$courseUsers = [
|
||||||
0 => ['UserId', 'Prénom', 'Nom', 'Page Titre', 'Consultation Date', 'Consultation Heure', 'Progression']
|
0 => ['UserId', 'Prénom', 'Nom', 'Mail', 'Page Titre', 'Consultation Date', 'Consultation Heure', 'Progression']
|
||||||
];
|
];
|
||||||
|
|
||||||
// Statistiques du contenu sélectionné calcul du nombre de pages
|
// Statistiques du contenu sélectionné calcul du nombre de pages
|
||||||
@ -1298,6 +1366,9 @@ class course extends common
|
|||||||
// Liste des inscrits dans le contenu sélectionné.
|
// Liste des inscrits dans le contenu sélectionné.
|
||||||
$users = $this->getData(['enrolment', $courseId]);
|
$users = $this->getData(['enrolment', $courseId]);
|
||||||
|
|
||||||
|
// Obtient les statistiques de l'ensemble de la cohorte
|
||||||
|
$reports = $this->getReport($courseId);
|
||||||
|
|
||||||
if (is_array($users)) {
|
if (is_array($users)) {
|
||||||
// Tri du tableau par défaut par $userId
|
// Tri du tableau par défaut par $userId
|
||||||
ksort($users);
|
ksort($users);
|
||||||
@ -1322,14 +1393,14 @@ class course extends common
|
|||||||
if (!empty($userValue['history'])) {
|
if (!empty($userValue['history'])) {
|
||||||
$maxTime = max($userValue['history']);
|
$maxTime = max($userValue['history']);
|
||||||
$lastPageId = array_search($maxTime, $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]);
|
$this->setData(['enrolment', $courseId, $userId, 'datePageView', $maxTime]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Progression
|
// Progression
|
||||||
$viewPages = $this->getData(['enrolment', $courseId, $userId, 'history']) !== null ?
|
$viewPages = array_key_exists($userId, $reports) ?
|
||||||
count(array_keys($this->getData(['enrolment', $courseId, $userId, 'history']))) :
|
count($reports[$userId]) :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
// Construction du tableau
|
// Construction du tableau
|
||||||
@ -1337,12 +1408,20 @@ class course extends common
|
|||||||
$userId,
|
$userId,
|
||||||
$this->getData(['user', $userId, 'firstname']),
|
$this->getData(['user', $userId, 'firstname']),
|
||||||
$this->getData(['user', $userId, 'lastname']),
|
$this->getData(['user', $userId, 'lastname']),
|
||||||
|
$this->getData(['user', $userId, 'mail']),
|
||||||
isset($pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])])
|
isset($pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])])
|
||||||
? $pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])]
|
? $pages[$this->getData(['enrolment', $courseId, $userId, 'lastPageView'])]
|
||||||
: $this->getData(['enrolment', $courseId, $userId, 'lastPageView']) . ' (supprimée)',
|
: $this->getData(['enrolment', $courseId, $userId, 'lastPageView']) . ' (supprimée)',
|
||||||
helper::dateUTF8('%d/%d/%Y', $this->getData(['enrolment', $courseId, $userId, 'datePageView'])),
|
helper::dateUTF8('%d/%d/%Y', $this->getData(['enrolment', $courseId, $userId, 'datePageView'])),
|
||||||
helper::dateUTF8('%H:%M', $this->getData(['enrolment', $courseId, $userId, 'datePageView'])),
|
helper::dateUTF8('%H:%M', $this->getData(['enrolment', $courseId, $userId, 'datePageView'])),
|
||||||
number_format(min(round(($viewPages * 100) / $sumPages, 1) / 100, 1), 2, ',')
|
/** La lecture de la progression s'effectue selon la nouvelle méthode (progression dans la base des enrolements)
|
||||||
|
* Soit avec l'ancienne méthode qui consiste à recalculer la progression.
|
||||||
|
* TRANSITOIRE A SUPPRIMER EN FIN D'ANNEE
|
||||||
|
**/
|
||||||
|
array_key_exists('progress', $userValue)
|
||||||
|
? $userValue['progress']
|
||||||
|
: ($viewPages ? min(round(($viewPages * 100) / $sumPages, 1), 100) . ' %' : '0%'),
|
||||||
|
//number_format(min(round(($viewPages * 100) / $sumPages, 1) / 100, 1), 2, ','),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Synthèse des historiques
|
// Synthèse des historiques
|
||||||
@ -1371,7 +1450,7 @@ class course extends common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userHistoryExport()
|
public function userReportExport()
|
||||||
{
|
{
|
||||||
|
|
||||||
$courseId = $this->getUrl(2);
|
$courseId = $this->getUrl(2);
|
||||||
@ -1388,17 +1467,18 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Traitement de l'historique
|
// Traitement de l'historique
|
||||||
$h = $this->getData(['enrolment', $courseId, $userId, 'history']);
|
$h = $this->getReport($courseId);
|
||||||
|
$h = $h[$userId];
|
||||||
|
|
||||||
// Inversion des clés et des valeurs
|
// Inversion des clés et des valeurs
|
||||||
$history = array();
|
$report = array();
|
||||||
foreach ($h as $key => $values) {
|
foreach ($h as $key => $values) {
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$history[$value] = $key;
|
$report[$value] = $key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($history);
|
ksort($report);
|
||||||
|
|
||||||
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
|
||||||
$p = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
$p = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/page.json'), true);
|
||||||
@ -1412,11 +1492,11 @@ class course extends common
|
|||||||
|
|
||||||
$lastView = 0;
|
$lastView = 0;
|
||||||
|
|
||||||
foreach ($history as $time => $pageId) {
|
foreach ($report as $time => $pageId) {
|
||||||
if (isset($pages[$pageId]['title'])) {
|
if (isset($pages[$pageId]['title'])) {
|
||||||
$lastView = ($lastView === 0) ? $time : $lastView;
|
$lastView = ($lastView === 0) ? $time : $lastView;
|
||||||
$diff = $time - $lastView;
|
$diff = $time - $lastView;
|
||||||
self::$userHistory[] = [
|
self::$userReport[] = [
|
||||||
$pageId,
|
$pageId,
|
||||||
html_entity_decode($pages[$pageId]['title']),
|
html_entity_decode($pages[$pageId]['title']),
|
||||||
$time,
|
$time,
|
||||||
@ -1429,16 +1509,16 @@ class course extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Décale les temps de consultation
|
// Décale les temps de consultation
|
||||||
for ($i = 0; $i < count(self::$userHistory) - 1; $i++) {
|
for ($i = 0; $i < count(self::$userReport) - 1; $i++) {
|
||||||
self::$userHistory[$i][3] = self::$userHistory[$i + 1][3];
|
self::$userReport[$i][3] = self::$userReport[$i + 1][3];
|
||||||
}
|
}
|
||||||
// Formate le timestamp
|
// Formate le timestamp
|
||||||
array_walk(self::$userHistory, function (&$item) {
|
array_walk(self::$userReport, function (&$item) {
|
||||||
$item[2] = helper::dateUTF8('%d/%m/%Y %H:%M:%S', $item[2]);
|
$item[2] = helper::dateUTF8('%d/%m/%Y %H:%M:%S', $item[2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ajoute les entêtes
|
// Ajoute les entêtes
|
||||||
self::$userHistory = array_merge([0 => ['PageId', 'Page Titre', 'Consultation Date', 'Temps Consultation']], self::$userHistory);
|
self::$userReport = array_merge([0 => ['PageId', 'Page Titre', 'Consultation Date', 'Temps Consultation']], self::$userReport);
|
||||||
|
|
||||||
// Dossier d'export
|
// Dossier d'export
|
||||||
if (is_dir(self::FILE_DIR . 'source/' . $courseId) === false) {
|
if (is_dir(self::FILE_DIR . 'source/' . $courseId) === false) {
|
||||||
@ -1451,7 +1531,7 @@ class course extends common
|
|||||||
|
|
||||||
$file = fopen($filename, 'w');
|
$file = fopen($filename, 'w');
|
||||||
|
|
||||||
foreach (self::$userHistory as $keys => $values) {
|
foreach (self::$userReport as $keys => $values) {
|
||||||
$data = $values;
|
$data = $values;
|
||||||
// Écrire la ligne dans le fichier CSV
|
// Écrire la ligne dans le fichier CSV
|
||||||
fputcsv($file, $data, ';');
|
fputcsv($file, $data, ';');
|
||||||
@ -1461,7 +1541,7 @@ class course extends common
|
|||||||
|
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'redirect' => helper::baseUrl() . 'course/userHistory/' . $courseId . '/' . $userId,
|
'redirect' => helper::baseUrl() . 'course/userReport/' . $courseId . '/' . $userId,
|
||||||
'notification' => 'Création ' . basename($filename) . ' dans le dossier "Export"',
|
'notification' => 'Création ' . basename($filename) . ' dans le dossier "Export"',
|
||||||
'state' => true,
|
'state' => true,
|
||||||
]);
|
]);
|
||||||
@ -1551,6 +1631,7 @@ class course extends common
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Désinscription d'un participant
|
* Désinscription d'un participant
|
||||||
|
* La désinscription ne supprime pas les historiques,
|
||||||
*/
|
*/
|
||||||
public function unsuscribe()
|
public function unsuscribe()
|
||||||
{
|
{
|
||||||
@ -1597,17 +1678,17 @@ class course extends common
|
|||||||
// Participants avec historiques
|
// Participants avec historiques
|
||||||
$enrolment = $this->getData(['enrolment', $courseId]);
|
$enrolment = $this->getData(['enrolment', $courseId]);
|
||||||
// Générer un fichier dans le dossier de l'espace
|
// Générer un fichier dans le dossier de l'espace
|
||||||
file_put_contents(self::DATA_DIR . $courseId . '/enrolment.json', json_encode([$courseId => $enrolment], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
$this->secure_file_put_contents(self::DATA_DIR . $courseId . '/enrolment.json', json_encode([$courseId => $enrolment], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
// Idem pour les données du cours
|
// Idem pour les données du cours
|
||||||
$course = $this->getData(['course', $courseId]);
|
$course = $this->getData(['course', $courseId]);
|
||||||
// Générer un fichier dans le dossier de l'espace
|
// Générer un fichier dans le dossier de l'espace
|
||||||
file_put_contents(self::DATA_DIR . $courseId . '/course.json', json_encode([$courseId => $course], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
$this->secure_file_put_contents(self::DATA_DIR . $courseId . '/course.json', json_encode([$courseId => $course], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
// Idem pour la catégorie
|
// Idem pour la catégorie
|
||||||
$category = $this->getData(['category', $this->getData(['course', $courseId, 'category'])]);
|
$category = $this->getData(['category', $this->getData(['course', $courseId, 'category'])]);
|
||||||
// Générer un fichier dans le dossier de l'espace
|
// Générer un fichier dans le dossier de l'espace
|
||||||
file_put_contents(self::DATA_DIR . $courseId . '/category.json', json_encode([$this->getData(['course', $courseId, 'category']) => $category], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
$this->secure_file_put_contents(self::DATA_DIR . $courseId . '/category.json', json_encode([$this->getData(['course', $courseId, 'category']) => $category], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
|
|
||||||
// Génère une archive ZIP
|
// Génère une archive ZIP
|
||||||
@ -1639,8 +1720,158 @@ class course extends common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Générer un fichier externe contenant le contenu des pages
|
||||||
|
public function export()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Espace sélectionné
|
||||||
|
$courseId = $this->getUrl(2);
|
||||||
|
|
||||||
|
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
|
||||||
|
if (
|
||||||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) === false
|
||||||
|
) {
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'access' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste des pages disponibles
|
||||||
|
$this->initDB('page', $courseId);
|
||||||
|
|
||||||
|
// Pointer RFM sur le dossier de l'espace
|
||||||
|
self::$siteContent = $courseId;
|
||||||
|
|
||||||
|
// Ordonne les pages par position
|
||||||
|
$this->buildHierarchy();
|
||||||
|
|
||||||
|
// Tableau de retour
|
||||||
|
self::$pagesList = [];
|
||||||
|
|
||||||
|
// Exclure les barres et les pages désactivées
|
||||||
|
foreach ($this->getData(['page']) as $pageId => $page) {
|
||||||
|
if (
|
||||||
|
$this->getData(['page', $pageId, 'block']) !== 'bar' &&
|
||||||
|
$this->getData(['page', $pageId, 'disable']) !== true
|
||||||
|
) {
|
||||||
|
self::$pagesList[] = template::checkbox('courseManageExport' . $pageId, true, $page['title'], [
|
||||||
|
'class' => 'courseManageCheckbox'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soumission du formulaire
|
||||||
|
if ($this->isPost()) {
|
||||||
|
$datas = '<h1>' . $this->getData(['course', $courseId, 'title']) . '</h1>';
|
||||||
|
$resources = [];
|
||||||
|
|
||||||
|
foreach ($this->getData(['page']) as $pageId => $page) {
|
||||||
|
if ($this->getInput('courseManageExport' . $pageId, helper::FILTER_BOOLEAN) === true) {
|
||||||
|
$pageContent = $this->getPage($pageId, $courseId);
|
||||||
|
|
||||||
|
// Extraction des URLs des ressources (images, vidéos, fichiers, etc.)
|
||||||
|
preg_match_all('/<img[^>]+src=["\'](.*?)["\']/i', $pageContent, $imgMatches); // Images
|
||||||
|
preg_match_all('/<a[^>]+href=["\'](.*?)["\']/i', $pageContent, $linkMatches); // Liens
|
||||||
|
preg_match_all('/<video[^>]+src=["\'](.*?)["\']/i', $pageContent, $videoMatches); // Vidéos directes
|
||||||
|
preg_match_all('/<source[^>]+src=["\'](.*?)["\']/i', $pageContent, $sourceMatches); // Vidéos dans balises <source>
|
||||||
|
|
||||||
|
// Traitement des images
|
||||||
|
$this->processResources($pageContent, '/<img[^>]+src=["\'](.*?)["\']/i', $resources);
|
||||||
|
|
||||||
|
// Traitement des vidéos directes via <video>
|
||||||
|
$this->processResources($pageContent, '/<video[^>]+src=["\'](.*?)["\']/i', $resources);
|
||||||
|
|
||||||
|
// Traitement des sources dans les balises <source> (utilisées dans <video> ou <audio>)
|
||||||
|
$this->processResources($pageContent, '/<source[^>]+src=["\'](.*?)["\']/i', $resources);
|
||||||
|
|
||||||
|
// Traitement des liens <a>
|
||||||
|
$this->processResources($pageContent, '/<a[^>]+href=["\'](.*?)["\']/i', $resources);
|
||||||
|
|
||||||
|
// Traitement des liens
|
||||||
|
if (!empty($linkMatches[1])) {
|
||||||
|
$resources = array_merge($resources, $linkMatches[1]);
|
||||||
|
|
||||||
|
// Remplacement des chemins pour les liens dans $pageContent
|
||||||
|
foreach ($linkMatches[1] as $resourceUrl) {
|
||||||
|
$resourcePath = parse_url($resourceUrl, PHP_URL_PATH);
|
||||||
|
$resourceFile = basename($resourcePath);
|
||||||
|
$pageContent = str_replace($resourceUrl, $resourceFile, $pageContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$datas .= $pageContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Créer le dossier d'export
|
||||||
|
$path = self::FILE_DIR . 'source/' . $courseId . '/';
|
||||||
|
if (is_dir($path . 'export') === false) {
|
||||||
|
mkdir($path . 'export');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copier les ressources dans le dossier d'export
|
||||||
|
foreach ($resources as $resourceUrl) {
|
||||||
|
$resourcePath = parse_url($resourceUrl, PHP_URL_PATH);
|
||||||
|
$resourceFile = basename($resourcePath);
|
||||||
|
if (file_exists($resourcePath)) { // Utilisation du chemin correct
|
||||||
|
copy($resourcePath, $path . 'export/' . $resourceFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajouter les balises HTML manquantes
|
||||||
|
$datas = '<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>' . $this->getData(['course', $courseId, 'title']) . '</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>' . $datas . '</body></html>';
|
||||||
|
|
||||||
|
// Sauvegarder le fichier HTML
|
||||||
|
file_put_contents($path . '/export/export_' . $this->getData(['course', $courseId, 'title']) . '.html', $datas, LOCK_EX);
|
||||||
|
|
||||||
|
// Copie une feuille de style
|
||||||
|
copy('core/module/course/resource/style.css', $path . 'export/style.css');
|
||||||
|
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'redirect' => helper::baseUrl() . 'course/manage/' . $courseId,
|
||||||
|
'notification' => helper::translate('Pages exportées dans le dossier de cet espace'),
|
||||||
|
'state' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'title' => sprintf('%s id : %s', helper::translate('Export des pages de l\'espace'), $this->getUrl(2)),
|
||||||
|
'view' => 'export'
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction utilisé par l'export en html pour corriger les URL des ressources
|
||||||
|
private function processResources(&$pageContent, $regex, &$resources)
|
||||||
|
{
|
||||||
|
preg_match_all($regex, $pageContent, $matches);
|
||||||
|
|
||||||
|
if (!empty($matches[1])) {
|
||||||
|
$resources = array_merge($resources, $matches[1]);
|
||||||
|
|
||||||
|
// Remplacement des chemins dans $pageContent
|
||||||
|
foreach ($matches[1] as $resourceUrl) {
|
||||||
|
$resourcePath = parse_url($resourceUrl, PHP_URL_PATH);
|
||||||
|
$resourceFile = basename($resourcePath);
|
||||||
|
$pageContent = str_replace($resourceUrl, $resourceFile, $pageContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sauvegarde d'un cours sans option
|
* Récupération d'un espace sans option
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function restore()
|
public function restore()
|
||||||
@ -1791,7 +2022,7 @@ class course extends common
|
|||||||
(
|
(
|
||||||
$this->getData(['enrolment', $courseId]) && ($this->getUser('id') === $this->getData(['course', $courseId, 'author']))
|
$this->getData(['enrolment', $courseId]) && ($this->getUser('id') === $this->getData(['course', $courseId, 'author']))
|
||||||
)
|
)
|
||||||
||
|
||
|
||||||
( // Permission d'accéder aux espaces dans lesquels le membre est inscrits
|
( // Permission d'accéder aux espaces dans lesquels le membre est inscrits
|
||||||
$this->getData(['enrolment', $courseId])
|
$this->getData(['enrolment', $courseId])
|
||||||
&& $this->getUser('permission', __CLASS__, 'tutor') === true
|
&& $this->getUser('permission', __CLASS__, 'tutor') === true
|
||||||
@ -1807,7 +2038,7 @@ class course extends common
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Autorise l'accès à un contenu
|
* 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é
|
* @param string $courseId identifiant du contenu sollicité
|
||||||
*/
|
*/
|
||||||
public function courseIsAvailable($courseId)
|
public function courseIsAvailable($courseId)
|
||||||
@ -1818,7 +2049,7 @@ class course extends common
|
|||||||
}
|
}
|
||||||
// Si un utilisateur connecté est admin ou auteur, c'est autorisé
|
// Si un utilisateur connecté est admin ou auteur, c'est autorisé
|
||||||
if (
|
if (
|
||||||
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') &&
|
$this->isConnected() === true &&
|
||||||
($this->getUser('group') === self::GROUP_ADMIN ||
|
($this->getUser('group') === self::GROUP_ADMIN ||
|
||||||
$this->getUser('id') === $this->getData(['course', $courseId, 'author']))
|
$this->getUser('id') === $this->getData(['course', $courseId, 'author']))
|
||||||
) {
|
) {
|
||||||
@ -1835,17 +2066,50 @@ class course extends common
|
|||||||
time() <= $this->getData(['course', $courseId, 'closingDate'])
|
time() <= $this->getData(['course', $courseId, 'closingDate'])
|
||||||
);
|
);
|
||||||
case self::COURSE_ACCESS_CLOSE:
|
case self::COURSE_ACCESS_CLOSE:
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode externe pour afficher la progression dans les espaces.
|
||||||
|
*
|
||||||
|
* @param mixed $courseId
|
||||||
|
* @param mixed $userId
|
||||||
|
* @return string Ratio de pages vues
|
||||||
|
*/
|
||||||
|
public function userProgress($courseId, $userId): string
|
||||||
|
{
|
||||||
|
|
||||||
|
// Obtient les statistiques de l'ensemble de la cohorte
|
||||||
|
$reports = $this->getReport($courseId, $userId);
|
||||||
|
|
||||||
|
// Nombre de pages dans l'espace
|
||||||
|
$viewPages = array_key_exists($userId, $reports) ?
|
||||||
|
count($reports[$userId]) :
|
||||||
|
0;
|
||||||
|
// Nombre de pages vues
|
||||||
|
$sumPages = $this->countPages($this->getData(['page']));
|
||||||
|
|
||||||
|
// Calcule le ratio
|
||||||
|
$ratio = number_format(min(round(($viewPages * 100) / $sumPages, 1) / 100, 1), 2, ',');
|
||||||
|
|
||||||
|
return $ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Compte les pages d'un espace
|
||||||
|
* @param mixed $array Tableau des pages de l'espace
|
||||||
|
* @return int Nombre de pages
|
||||||
|
*/
|
||||||
private function countPages($array)
|
private function countPages($array)
|
||||||
{
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
foreach ($array as $key => $value) {
|
foreach ($array as $pageId => $pageData) {
|
||||||
$count++; // Incrémente le compteur pour chaque clé associative trouvée
|
if ($pageData['position'] > 0) {
|
||||||
if (is_array($value)) {
|
$count++;
|
||||||
$count += $this->countPages($value); // Appelle récursivement la fonction si la valeur est un tableau
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $count;
|
return $count;
|
||||||
@ -1858,14 +2122,16 @@ class course extends common
|
|||||||
$courseId,
|
$courseId,
|
||||||
$userId,
|
$userId,
|
||||||
[
|
[
|
||||||
'history' => [],
|
'lastPageView' => '',
|
||||||
|
'datePageView' => '',
|
||||||
|
'progress' => '',
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autorise l'accès à un contenu
|
* 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 $userId identifiant de l'utilisateur
|
||||||
* @param string $courseId identifiant du contenu sollicité
|
* @param string $courseId identifiant du contenu sollicité
|
||||||
*/
|
*/
|
||||||
@ -1878,10 +2144,11 @@ class course extends common
|
|||||||
$r = true;
|
$r = true;
|
||||||
break;
|
break;
|
||||||
case self::GROUP_EDITOR:
|
case self::GROUP_EDITOR:
|
||||||
$r = in_array($userId, array_keys($this->getData(['enrolment', $courseId])));
|
|
||||||
break;
|
|
||||||
case self::GROUP_MEMBER:
|
case self::GROUP_MEMBER:
|
||||||
$r = in_array($userId, array_keys($this->getData(['enrolment', $courseId])));
|
$r = false;
|
||||||
|
if (!is_null($this->getData(['enrolment', $courseId]))) {
|
||||||
|
$r = in_array($userId, array_keys($this->getData(['enrolment', $courseId])));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Visiteur non connecté
|
// Visiteur non connecté
|
||||||
case self::GROUP_VISITOR:
|
case self::GROUP_VISITOR:
|
||||||
@ -1894,4 +2161,52 @@ class course extends common
|
|||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lit le contenu des fichiers de traces au format CS et renvoie un tableau associatif
|
||||||
|
*/
|
||||||
|
private function getReport($courseId, $userId = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
if (file_exists(self::DATA_DIR . $courseId . '/report.csv')) {
|
||||||
|
// Remplacez 'chemin/vers/votre/fichier.csv' par le chemin réel de votre fichier CSV
|
||||||
|
$file = fopen(self::DATA_DIR . $courseId . '/report.csv', "r");
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
// Lire ligne par ligne
|
||||||
|
while (($line = fgetcsv($file, 1000, ";")) !== false) {
|
||||||
|
$name = $line[0];
|
||||||
|
$pageId = $line[1];
|
||||||
|
$timestamp = $line[2];
|
||||||
|
// Filtre 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
|
||||||
|
fclose($file);
|
||||||
|
|
||||||
|
// Trier les timestamps
|
||||||
|
foreach ($data as &$userData) {
|
||||||
|
foreach ($userData as &$pageData) {
|
||||||
|
sort($pageData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afficher le JSON;
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
}
|
}
|
98
core/module/course/resource/style.css
Normal file
98
core/module/course/resource/style.css
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* Réinitialisation de base pour supprimer les marges et les espacements par défaut */
|
||||||
|
body, h1, h2, h3, h4, h5, h6, p, ul, ol, li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 20px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header, .footer {
|
||||||
|
background-color: #34495e;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1, .footer p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border: 1px solid #e1e1e1;
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-family: "Courier New", Courier, monospace;
|
||||||
|
color: #c7254e;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border: 1px solid #e1e1e1;
|
||||||
|
padding: 10px;
|
||||||
|
font-family: "Courier New", Courier, monospace;
|
||||||
|
overflow-x: auto;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media Queries pour rendre la page responsive */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col6">
|
||||||
<?php echo template::select('courseEditHomePageId', helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC'), [
|
<?php echo template::select('courseEditHomePageId', helper::arrayColumn($module::$pagesList, 'title'), [
|
||||||
'label' => 'Page d\'accueil',
|
'label' => 'Page d\'accueil',
|
||||||
'selected' => $this->getdata(['course', $this->getUrl(2), 'homePageId']),
|
'selected' => $this->getdata(['course', $this->getUrl(2), 'homePageId']),
|
||||||
]); ?>
|
]); ?>
|
||||||
|
18
core/module/course/view/export/export.css
Normal file
18
core/module/course/view/export/export.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of Zwii.
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
* @author Rémi Jean <remi.jean@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||||
|
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
|
||||||
|
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
|
||||||
|
* @link http://zwiicms.fr/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** NE PAS EFFACER
|
||||||
|
* admin.css
|
||||||
|
*/
|
27
core/module/course/view/export/export.js.php
Normal file
27
core/module/course/view/export/export.js.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
// Quand le bouton "Cocher toutes" est cliqué
|
||||||
|
$('#courseExportSelectAll').on('click', function() {
|
||||||
|
// Cocher toutes les checkboxes avec la classe 'courseManageCheckbox'
|
||||||
|
$('.courseManageCheckbox').prop('checked', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quand le bouton "Décocher toutes" est cliqué
|
||||||
|
$('#courseExportSelectNone').on('click', function() {
|
||||||
|
// Décocher toutes les checkboxes avec la classe 'courseManageCheckbox'
|
||||||
|
$('.courseManageCheckbox').prop('checked', false);
|
||||||
|
});
|
||||||
|
});
|
42
core/module/course/view/export/export.php
Normal file
42
core/module/course/view/export/export.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php echo template::formOpen('courseExportForm'); ?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col1">
|
||||||
|
<?php echo template::button('courseExportBack', [
|
||||||
|
'class' => 'buttonGrey',
|
||||||
|
'href' => helper::baseUrl() . 'course/manage/' . $this->getUrl(2),
|
||||||
|
'value' => template::ico('left')
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 offset7">
|
||||||
|
<?php echo template::button('courseExportSelectAll', [
|
||||||
|
'value' => template::ico('square-check'),
|
||||||
|
'help' => 'Tout sélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1">
|
||||||
|
<?php echo template::button('courseExportSelectNone', [
|
||||||
|
'value' => template::ico('square-check-empty'),
|
||||||
|
'help' => 'Tout désélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<?php echo template::submit('courseExportSubmit', [
|
||||||
|
'value' => 'Valider'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col12">
|
||||||
|
<div class="block">
|
||||||
|
<h4><?php echo helper::translate('Sélection des pages de l\'espace') ?></h4>
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col10 offset2'>
|
||||||
|
<?php foreach ($module::$pagesList as $key => $value) {
|
||||||
|
echo $value;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -18,11 +18,22 @@ $(document).ready(function () {
|
|||||||
},
|
},
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
|
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
target: 2,
|
target: 2,
|
||||||
orderable: false,
|
orderable: false,
|
||||||
searchable: false
|
searchable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
target: 3,
|
||||||
|
orderable: false,
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
target: 4,
|
||||||
|
orderable: false,
|
||||||
|
searchable: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($module::$courses): ?>
|
<?php if ($module::$courses): ?>
|
||||||
<?php echo template::table([4, 4, 3, 1], $module::$courses, ['Titre court', 'Description', 'Inscription', '',], ['id' => 'dataTables']); ?>
|
<?php echo template::table([4, 3, 3, 1, 1], $module::$courses, ['Titre court', 'Description', 'Inscription', '', '',], ['id' => 'dataTables']); ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php echo template::speech('Aucun espace'); ?>
|
<?php echo template::speech('Aucun espace'); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
@ -20,4 +20,15 @@ $(".courseDelete").on("click", function () {
|
|||||||
return core.confirm(message, function () {
|
return core.confirm(message, function () {
|
||||||
$(location).attr("href", _this.attr("href"));
|
$(location).attr("href", _this.attr("href"));
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirmation de suppression
|
||||||
|
*/
|
||||||
|
$(".courseReset").on("click", function () {
|
||||||
|
var _this = $(this);
|
||||||
|
var message = "<?php echo helper::translate('Réinitialiser cet espace ?'); ?>";
|
||||||
|
return core.confirm(message, function () {
|
||||||
|
$(location).attr("href", _this.attr("href"));
|
||||||
|
});
|
||||||
});
|
});
|
@ -14,7 +14,19 @@
|
|||||||
'class' => 'courseDelete buttonRed',
|
'class' => 'courseDelete buttonRed',
|
||||||
'href' => helper::baseUrl() . 'course/delete/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'course/delete/' . $this->getUrl(2),
|
||||||
'value' => 'Supprimer',
|
'value' => 'Supprimer',
|
||||||
'ico' => 'trash'
|
'ico' => 'trash',
|
||||||
|
'help' => 'Supprime l\'espace et les historiques des participants',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($this->getUser('permission', 'course', 'reset') === true): ?>
|
||||||
|
<div class="col2 ">
|
||||||
|
<?php echo template::button('courseManageReset' . $this->getUrl(2), [
|
||||||
|
'class' => 'courseReset buttonRed',
|
||||||
|
'href' => helper::baseUrl() . 'course/reset/' . $this->getUrl(2),
|
||||||
|
'value' => 'Réinitaliser',
|
||||||
|
'ico' => 'cancel',
|
||||||
|
'help' => 'Désinscrit les participants et supprime les historiques',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -23,7 +35,8 @@
|
|||||||
<?php echo template::button('courseManageDownload' . $this->getUrl(2), [
|
<?php echo template::button('courseManageDownload' . $this->getUrl(2), [
|
||||||
'href' => helper::baseUrl() . 'course/backup/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'course/backup/' . $this->getUrl(2),
|
||||||
'value' => 'Sauvegarder',
|
'value' => 'Sauvegarder',
|
||||||
'ico' => 'download-cloud'
|
'ico' => 'download-cloud',
|
||||||
|
'help' => 'Génère une copie de sauvegarde de l\'espace',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -32,32 +45,33 @@
|
|||||||
<?php echo template::button('courseManageDuplicate' . $this->getUrl(2), [
|
<?php echo template::button('courseManageDuplicate' . $this->getUrl(2), [
|
||||||
'href' => helper::baseUrl() . 'course/clone/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'course/clone/' . $this->getUrl(2),
|
||||||
'value' => 'Cloner',
|
'value' => 'Cloner',
|
||||||
'ico' => 'clone'
|
'ico' => 'clone',
|
||||||
|
'help' => 'Copie l\'espace et son contenu sans les participants et leurs historiques',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if ($this->getUser('permission', 'course', 'edit') === true): ?>
|
<?php if ($this->getUser('permission', 'course', 'edit') === true): ?>
|
||||||
<div class="col2">
|
<div class="col2">
|
||||||
|
|
||||||
<?php echo template::button('courseManageEdit' . $this->getUrl(2), [
|
<?php echo template::button('courseManageEdit' . $this->getUrl(2), [
|
||||||
'href' => helper::baseUrl() . 'course/edit/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'course/edit/' . $this->getUrl(2),
|
||||||
'value' => 'Éditer',
|
'value' => 'Éditer',
|
||||||
'ico' => 'pencil'
|
'ico' => 'pencil',
|
||||||
|
'help' => 'Modifie les paramètres de l\'espace',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if ($this->getUser('permission', 'course', 'users') === true): ?>
|
<?php if ($this->getUser('permission', 'course', 'export') === true): ?>
|
||||||
<div class="col2">
|
<div class="col2">
|
||||||
|
<?php echo template::button('courseManageExport' . $this->getUrl(2), [
|
||||||
<?php echo template::button('categoryUser' . $this->getUrl(2), [
|
'href' => helper::baseUrl() . 'course/export/' . $this->getUrl(2),
|
||||||
'href' => helper::baseUrl() . 'course/users/' . $this->getUrl(2),
|
'value' => 'Exporter HTML',
|
||||||
'value' => 'Participants',
|
'ico' => 'upload',
|
||||||
'ico' => 'users'
|
'help' => 'Le contenu de l\'espace est exporté dans une page web autonome',
|
||||||
]); ?>
|
]); ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col12">
|
<div class="col12">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col1 offset10">
|
<div class="col1 offset10">
|
||||||
<?php echo template::button('userDeleteAll', [
|
<?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'),
|
'value' => template::ico('download'),
|
||||||
'help' => 'Exporter',
|
'help' => 'Exporter',
|
||||||
]) ?>
|
]) ?>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($module::$userHistory): ?>
|
<?php if ($module::$userReport): ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col4 offset2">
|
<div class="col4 offset2">
|
||||||
<?php if ($this->getData(['course', $this->getUrl(2), 'access']) === self::COURSE_ACCESS_DATE): ?>
|
<?php if ($this->getData(['course', $this->getUrl(2), 'access']) === self::COURSE_ACCESS_DATE): ?>
|
||||||
@ -46,7 +46,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row textAlignCenter">
|
<div class="row textAlignCenter">
|
||||||
<div class="col8">
|
<div class="col8">
|
||||||
<?php echo template::table([6, 3, 3], $module::$userHistory, ['Page', 'Début de Consultation', 'Temps consultation']); ?>
|
<?php echo template::table([6, 3, 3], $module::$userReport, ['Page', 'Début de Consultation', 'Temps consultation']); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
@ -29,6 +29,7 @@ $(document).ready((function () {
|
|||||||
order: [[3, 'desc']],
|
order: [[3, 'desc']],
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
|
"lengthMenu": [[10, 25, 50, 100, 299, -1], [10, 25, 50, 100, 200, "Tout"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
target: 6,
|
target: 6,
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
<div class="col1">
|
<div class="col1">
|
||||||
<?php echo template::button('courseUserBack', [
|
<?php echo template::button('courseUserBack', [
|
||||||
'class' => 'buttonGrey',
|
'class' => 'buttonGrey',
|
||||||
'href' => helper::baseUrl() . 'course/manage/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'course/' . $this->getUrl(2),
|
||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1 offset8">
|
<div class="col1 offset8">
|
||||||
<?php echo template::button('userDeleteAll', [
|
<?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'),
|
'value' => template::ico('download'),
|
||||||
'help' => 'Exporter',
|
'help' => 'Exporter',
|
||||||
]) ?>
|
]) ?>
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
* admin.css
|
* admin.css
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#courseUserAddSelectAll {
|
tr {
|
||||||
color: lightgreen;
|
cursor: pointer;
|
||||||
}
|
|
||||||
|
|
||||||
#courseUserAddSelectNone {
|
|
||||||
color: lightcoral;
|
|
||||||
}
|
}
|
@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
$(document).ready((function () {
|
$(document).ready((function () {
|
||||||
|
|
||||||
|
$('tr').click(function(){
|
||||||
|
// Cochez ou décochez la case à cocher dans cette ligne
|
||||||
|
$(this).find('input[type="checkbox"]').prop('checked', function(i, val){
|
||||||
|
return !val; // Inverse l'état actuel de la case à cocher
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('#courseUserAddSelectAll').on('click', function() {
|
$('#courseUserAddSelectAll').on('click', function() {
|
||||||
$('.checkboxSelect').prop('checked', true);
|
$('.checkboxSelect').prop('checked', true);
|
||||||
saveCheckboxState();
|
saveCheckboxState();
|
||||||
@ -33,6 +40,7 @@ $(document).ready((function () {
|
|||||||
},
|
},
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
|
"lengthMenu": [[10, 25, 50, 100, 299, -1], [10, 25, 50, 100, 200, "Tout"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
target: 0,
|
target: 0,
|
||||||
|
@ -7,21 +7,9 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1 offset8">
|
<div class="col2 offset9">
|
||||||
<?php echo template::button('courseUserAddSelectAll', [
|
|
||||||
'value' => template::ico('check'),
|
|
||||||
'help' => 'Tout sélectionner'
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col1">
|
|
||||||
<?php echo template::button('courseUserAddSelectNone', [
|
|
||||||
'value' => template::ico('cancel'),
|
|
||||||
'help' => 'Tout désélectionner'
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col1">
|
|
||||||
<?php echo template::submit('courseUsersAddSubmit', [
|
<?php echo template::submit('courseUsersAddSubmit', [
|
||||||
'value' => '',
|
'value' => 'Inscrire',
|
||||||
'ico' => 'plus',
|
'ico' => 'plus',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
@ -45,6 +33,18 @@
|
|||||||
'selected' => isset($_POST['courseFilterLastName']) ? $_POST['courseFilterLastName'] : 'all',
|
'selected' => isset($_POST['courseFilterLastName']) ? $_POST['courseFilterLastName'] : 'all',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col1 offset1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('courseUserAddSelectAll', [
|
||||||
|
'value' => template::ico('square-check'),
|
||||||
|
'help' => 'Tout sélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('courseUserAddSelectNone', [
|
||||||
|
'value' => template::ico('square-check-empty'),
|
||||||
|
'help' => 'Tout désélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($module::$courseUsers): ?>
|
<?php if ($module::$courseUsers): ?>
|
||||||
<?php echo template::table([1, 2, 3, 3, 3], $module::$courseUsers, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
<?php echo template::table([1, 2, 3, 3, 3], $module::$courseUsers, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
background-color: rgba(217, 95, 78, 1);
|
background-color: rgba(217, 95, 78, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#courseUserDeleteSelectAll {
|
tr {
|
||||||
color: lightgreen;
|
cursor: pointer;
|
||||||
}
|
|
||||||
|
|
||||||
#courseUserDeleteSelectNone {
|
|
||||||
color: lightcoral;
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
$(document).ready((function () {
|
$(document).ready((function () {
|
||||||
|
|
||||||
|
$('tr').click(function () {
|
||||||
|
// Cochez ou décochez la case à cocher dans cette ligne
|
||||||
|
$(this).find('input[type="checkbox"]').prop('checked', function (i, val) {
|
||||||
|
return !val; // Inverse l'état actuel de la case à cocher
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('#courseUserDeleteSelectAll').on('click', function () {
|
$('#courseUserDeleteSelectAll').on('click', function () {
|
||||||
$('.checkboxSelect').prop('checked', true);
|
$('.checkboxSelect').prop('checked', true);
|
||||||
saveCheckboxState();
|
saveCheckboxState();
|
||||||
@ -32,6 +39,7 @@ $(document).ready((function () {
|
|||||||
url: "core/vendor/datatables/french.json"
|
url: "core/vendor/datatables/french.json"
|
||||||
},
|
},
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
|
"lengthMenu": [[10, 25, 50, 100, 299, -1], [10, 25, 50, 100, 200, "Tout"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
target: 0,
|
target: 0,
|
||||||
|
@ -7,26 +7,14 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1 offset8">
|
<div class="col2 offset9">
|
||||||
<?php echo template::button('courseUserDeleteSelectAll', [
|
|
||||||
'value' => template::ico('check'),
|
|
||||||
'help' => 'Tout sélectionner'
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col1">
|
|
||||||
<?php echo template::button('courseUserDeleteSelectNone', [
|
|
||||||
'value' => template::ico('cancel'),
|
|
||||||
'help' => 'Tout désélectionner'
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col1">
|
|
||||||
<?php echo template::submit('courseUsersDeleteSubmit', [
|
<?php echo template::submit('courseUsersDeleteSubmit', [
|
||||||
'class' => 'buttonRed',
|
'class' => 'buttonRed',
|
||||||
'ico' => '',
|
'ico' => 'minus',
|
||||||
'value' => template::ico('minus'),
|
'value' => 'Désinscrire',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" id="Bfrtip">
|
<div class="row" id="Bfrtip">
|
||||||
<div class="col3">
|
<div class="col3">
|
||||||
<?php echo template::select('courseFilterGroup', $module::$courseGroups, [
|
<?php echo template::select('courseFilterGroup', $module::$courseGroups, [
|
||||||
@ -46,9 +34,21 @@
|
|||||||
'selected' => isset($_POST['courseFilterLastName']) ? $_POST['courseFilterLastName'] : 'all',
|
'selected' => isset($_POST['courseFilterLastName']) ? $_POST['courseFilterLastName'] : 'all',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col1 offset1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('courseUserDeleteSelectAll', [
|
||||||
|
'value' => template::ico('square-check'),
|
||||||
|
'help' => 'Tout sélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('courseUserDeleteSelectNone', [
|
||||||
|
'value' => template::ico('square-check-empty'),
|
||||||
|
'help' => 'Tout désélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($module::$courseUsers): ?>
|
<?php if ($module::$courseUsers): ?>
|
||||||
<?php echo template::table([1, 2, 3, 3, 3], $module::$courseUsers, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
<?php echo template::table([1, 2, 3, 3, 3], $module::$courseUsers, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php echo template::speech('Aucun inscrit'); ?>
|
<?php echo template::speech('Aucun inscrit'); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
@ -158,9 +158,9 @@ class install extends common
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Sauvegarder la configuration du Proxy
|
// Sauvegarder la configuration du Proxy
|
||||||
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')]);
|
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')], false);
|
||||||
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
|
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')], false);
|
||||||
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
|
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)], false);
|
||||||
|
|
||||||
// Images exemples livrées dans tous les cas
|
// Images exemples livrées dans tous les cas
|
||||||
try {
|
try {
|
||||||
@ -203,7 +203,7 @@ class install extends common
|
|||||||
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
|
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
|
||||||
|
|
||||||
// Fixe l'adresse from pour les envois d'email
|
// 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
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
@ -212,9 +212,10 @@ class install extends common
|
|||||||
'state' => true
|
'state' => true
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
// Force la sauvegarde
|
||||||
|
$this->saveDB('config');
|
||||||
|
|
||||||
// Affichage du formulaire
|
// Affichage du formulaire
|
||||||
|
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||||
@ -387,7 +388,7 @@ class install extends common
|
|||||||
'</IfModule>' . PHP_EOL .
|
'</IfModule>' . PHP_EOL .
|
||||||
'# URL rewriting' . PHP_EOL;
|
'# URL rewriting' . PHP_EOL;
|
||||||
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
|
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
|
||||||
$success = file_put_contents(
|
$success = $this->secure_file_put_contents(
|
||||||
'.htaccess',
|
'.htaccess',
|
||||||
$fileContent
|
$fileContent
|
||||||
);
|
);
|
||||||
|
@ -246,13 +246,14 @@ class init extends common
|
|||||||
'manage' => false,
|
'manage' => false,
|
||||||
'users' => false,
|
'users' => false,
|
||||||
'userHistory' => false,
|
'userHistory' => false,
|
||||||
'userHistoryExport' => false,
|
'userReportExport' => false,
|
||||||
'usersAdd' => false,
|
'usersAdd' => false,
|
||||||
'userDelete' => false,
|
'userDelete' => false,
|
||||||
'usersDelete' => false,
|
'usersDelete' => false,
|
||||||
'edit' => false,
|
'edit' => false,
|
||||||
'backup' => false,
|
'backup' => false,
|
||||||
'restore' => false
|
'restore' => false,
|
||||||
|
'reset' => false,
|
||||||
],
|
],
|
||||||
'folder' => [
|
'folder' => [
|
||||||
'create' => false,
|
'create' => false,
|
||||||
@ -342,13 +343,14 @@ class init extends common
|
|||||||
'manage' => false,
|
'manage' => false,
|
||||||
'users' => false,
|
'users' => false,
|
||||||
'userHistory' => false,
|
'userHistory' => false,
|
||||||
'userHistoryExport' => false,
|
'userReportExport' => false,
|
||||||
'usersAdd' => false,
|
'usersAdd' => false,
|
||||||
'userDelete' => false,
|
'userDelete' => false,
|
||||||
'usersDelete' => false,
|
'usersDelete' => false,
|
||||||
'edit' => false,
|
'edit' => false,
|
||||||
'backup' => false,
|
'backup' => false,
|
||||||
'restore' => false
|
'restore' => false,
|
||||||
|
'reset' => false,
|
||||||
],
|
],
|
||||||
'folder' => [
|
'folder' => [
|
||||||
'create' => false,
|
'create' => false,
|
||||||
@ -443,13 +445,14 @@ class init extends common
|
|||||||
'manage' => true,
|
'manage' => true,
|
||||||
'users' => true,
|
'users' => true,
|
||||||
'userHistory' => true,
|
'userHistory' => true,
|
||||||
'userHistoryExport' => true,
|
'userReportExport' => true,
|
||||||
'usersAdd' => true,
|
'usersAdd' => true,
|
||||||
'userDelete' => false,
|
'userDelete' => false,
|
||||||
'usersDelete' => false,
|
'usersDelete' => false,
|
||||||
'edit' => false,
|
'edit' => false,
|
||||||
'backup' => false,
|
'backup' => false,
|
||||||
'restore' => false
|
'restore' => false,
|
||||||
|
'reset' => false,
|
||||||
],
|
],
|
||||||
'folder' => [
|
'folder' => [
|
||||||
'create' => false,
|
'create' => false,
|
||||||
@ -540,13 +543,14 @@ class init extends common
|
|||||||
'manage' => true,
|
'manage' => true,
|
||||||
'users' => true,
|
'users' => true,
|
||||||
'userHistory' => true,
|
'userHistory' => true,
|
||||||
'userHistoryExport' => true,
|
'userReportExport' => true,
|
||||||
'usersAdd' => true,
|
'usersAdd' => true,
|
||||||
'userDelete' => true,
|
'userDelete' => true,
|
||||||
'usersDelete' => true,
|
'usersDelete' => true,
|
||||||
'edit' => true,
|
'edit' => true,
|
||||||
'backup' => true,
|
'backup' => true,
|
||||||
'restore' => true
|
'restore' => true,
|
||||||
|
'reset' => true,
|
||||||
],
|
],
|
||||||
'folder' => [
|
'folder' => [
|
||||||
'create' => true,
|
'create' => true,
|
||||||
|
@ -99,7 +99,7 @@ class language extends common
|
|||||||
is_array($descripteur['language'][$lang])
|
is_array($descripteur['language'][$lang])
|
||||||
) {
|
) {
|
||||||
if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) {
|
if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) {
|
||||||
$success = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($languageData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
$success = $this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($languageData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
$success = is_int($success) ? true : false;
|
$success = is_int($success) ? true : false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ class page extends common
|
|||||||
'edit' => self::GROUP_EDITOR,
|
'edit' => self::GROUP_EDITOR,
|
||||||
'duplicate' => self::GROUP_EDITOR,
|
'duplicate' => self::GROUP_EDITOR,
|
||||||
'jsEditor' => self::GROUP_EDITOR,
|
'jsEditor' => self::GROUP_EDITOR,
|
||||||
'cssEditor' => self::GROUP_EDITOR
|
'cssEditor' => self::GROUP_EDITOR,
|
||||||
|
'register' => self::GROUP_EDITOR,
|
||||||
];
|
];
|
||||||
public static $pagesNoParentId = [
|
public static $pagesNoParentId = [
|
||||||
'' => 'Aucune'
|
'' => 'Aucune'
|
||||||
@ -85,12 +86,23 @@ class page extends common
|
|||||||
*/
|
*/
|
||||||
public function duplicate()
|
public function duplicate()
|
||||||
{
|
{
|
||||||
|
// La session ne correspond pas au site ouvert dans cet onglet
|
||||||
|
if (
|
||||||
|
// Contrôle la présence de l'id d'espace uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
|
||||||
|
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
|
||||||
|
) {
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
|
||||||
|
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
// Adresse sans le token
|
// Adresse sans le token
|
||||||
$page = $this->getUrl(2);
|
$page = $this->getUrl(2);
|
||||||
|
|
||||||
// La page n'existe pas
|
// La page n'existe pas
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
$this->getData(['page', $page]) === null
|
|| $this->getData(['page', $page]) === null
|
||||||
) {
|
) {
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
@ -107,18 +119,20 @@ class page extends common
|
|||||||
$page
|
$page
|
||||||
]);
|
]);
|
||||||
// Ecriture
|
// Ecriture
|
||||||
$this->setData(['page', $pageId, $data]);
|
$this->setData(['page', $pageId, $data], false);
|
||||||
$notification = helper::translate('Page dupliquée');
|
$notification = helper::translate('Page dupliquée');
|
||||||
// Duplication du module présent
|
// Duplication du module présent
|
||||||
if ($this->getData(['page', $page, 'moduleId'])) {
|
if ($this->getData(['page', $page, 'moduleId'])) {
|
||||||
$data = $this->getData(['module', $page]);
|
$data = $this->getData(['module', $page]);
|
||||||
$this->setData(['module', $pageId, $data]);
|
$this->setData(['module', $pageId, $data], false);
|
||||||
$notification = helper::translate('Page et module dupliqués');
|
$notification = helper::translate('Page et module dupliqués');
|
||||||
}
|
}
|
||||||
|
// Force la sauvegarde
|
||||||
|
$this->saveDB('page');
|
||||||
|
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
|
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId . '/' . self::$siteContent,
|
||||||
'notification' => $notification,
|
'notification' => $notification,
|
||||||
'state' => true
|
'state' => true
|
||||||
]);
|
]);
|
||||||
@ -131,7 +145,19 @@ class page extends common
|
|||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
|
// La session ne correspond pas au site ouvert dans cet onglet
|
||||||
|
if (
|
||||||
|
// Contrôle la présence de l'id d'espace uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
|
||||||
|
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
|
||||||
|
) {
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
|
||||||
|
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
|
) {
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'access' => false
|
'access' => false
|
||||||
@ -180,8 +206,8 @@ class page extends common
|
|||||||
//file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
|
//file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
|
||||||
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$siteContent);
|
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$siteContent);
|
||||||
|
|
||||||
// Met à jour le sitemap
|
// Ne met à jour le sitemap pour éviter un warning, de toute manière la nouvelle page doit être éditée.
|
||||||
$this->updateSitemap();
|
// $this->updateSitemap();
|
||||||
|
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
@ -198,12 +224,24 @@ class page extends common
|
|||||||
*/
|
*/
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// La session ne correspond pas au site ouvert dans cet onglet
|
||||||
|
if (
|
||||||
|
// Contrôle la présence de l'id d'espace uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
|
||||||
|
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
|
||||||
|
) {
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
|
||||||
|
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
// $url prend l'adresse sans le token
|
// $url prend l'adresse sans le token
|
||||||
$page = $this->getUrl(2);
|
$page = $this->getUrl(2);
|
||||||
|
|
||||||
// La page n'existe pas
|
// La page n'existe pas
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
$this->getData(['page', $page]) === null
|
|| $this->getData(['page', $page]) === null
|
||||||
) {
|
) {
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
@ -215,9 +253,9 @@ class page extends common
|
|||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'redirect' => helper::baseUrl() . $this->homePageId(),
|
'redirect' => helper::baseUrl() . $this->homePageId(),
|
||||||
'notification' => self::$siteContent === 'home'
|
'notification' => self::$siteContent === 'home'
|
||||||
? helper::translate('Suppression interdite, cette page est définie comme page d\'accueil du site')
|
? helper::translate('Suppression interdite, cette page est définie comme page d\'accueil du site')
|
||||||
: helper::translate('Suppression interdite, cette page est définie comme page d\'accueil d\'un espace')
|
: helper::translate('Suppression interdite, cette page est définie comme page d\'accueil d\'un espace')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
// Impossible de supprimer la page affectée
|
// Impossible de supprimer la page affectée
|
||||||
@ -264,7 +302,7 @@ class page extends common
|
|||||||
elseif ($this->getHierarchy($page, null)) {
|
elseif ($this->getHierarchy($page, null)) {
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'redirect' => helper::baseUrl() . 'page/edit/' . $page,
|
'redirect' => helper::baseUrl() . 'page/edit/' . $page . '/' . self::$siteContent,
|
||||||
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
|
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -304,10 +342,24 @@ class page extends common
|
|||||||
*/
|
*/
|
||||||
public function edit()
|
public function edit()
|
||||||
{
|
{
|
||||||
|
// La session ne correspond pas au site ouvert dans cet onglet
|
||||||
|
if (
|
||||||
|
// Contrôle la présence de l'id d'espace uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
|
||||||
|
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
|
||||||
|
) {
|
||||||
|
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
|
||||||
|
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
// La page n'existe pas
|
// La page n'existe pas
|
||||||
if (
|
if (
|
||||||
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
$this->getData(['page', $this->getUrl(2)]) === null
|
|| $this->getData(['page', $this->getUrl(2)]) === null
|
||||||
|
// Contrôle la présence de l'id d'espace uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
|
||||||
|
|| (
|
||||||
|
$this->getUrl(3)
|
||||||
|
&& $this->getUrl(3) != self::$siteContent
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
@ -341,11 +393,11 @@ class page extends common
|
|||||||
$pageId = helper::increment($pageId, self::$moduleIds);
|
$pageId = helper::increment($pageId, self::$moduleIds);
|
||||||
// Met à jour les enfants
|
// Met à jour les enfants
|
||||||
foreach ($this->getHierarchy($this->getUrl(2), null) as $childrenPageId) {
|
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
|
// Change l'id de page dans les données des modules
|
||||||
if ($this->getData(['module', $this->getUrl(2)]) !== null) {
|
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)]);
|
$this->deleteData(['module', $this->getUrl(2)]);
|
||||||
// Renommer le dossier du module
|
// Renommer le dossier du module
|
||||||
$moduleId = $this->getData(['page', $this->getUrl(2), 'moduleId']);
|
$moduleId = $this->getData(['page', $this->getUrl(2), 'moduleId']);
|
||||||
@ -356,8 +408,10 @@ class page extends common
|
|||||||
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
|
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
|
||||||
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
|
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
|
||||||
// Mettre à jour le nom de la feuille de style
|
// Mettre à jour le nom de la feuille de style
|
||||||
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId]);
|
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId], false);
|
||||||
}
|
}
|
||||||
|
// Sauvegarde la base manuellement
|
||||||
|
$this->saveDB('module');
|
||||||
}
|
}
|
||||||
// Met à jour les historiques des utilisateurs
|
// Met à jour les historiques des utilisateurs
|
||||||
foreach ($this->getData(['enrolment', self::$siteContent]) as $userId => $userData) {
|
foreach ($this->getData(['enrolment', self::$siteContent]) as $userId => $userData) {
|
||||||
@ -368,14 +422,17 @@ class page extends common
|
|||||||
) {
|
) {
|
||||||
// Remplacer l'ancienne ID par la nouvelle
|
// Remplacer l'ancienne ID par la nouvelle
|
||||||
$datas = $this->getData(['enrolment', self::$siteContent, $userId, 'history', $this->getUrl(2)]);
|
$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)]);
|
$this->deleteData(['enrolment', self::$siteContent, $userId, 'history', $this->getUrl(2)]);
|
||||||
}
|
}
|
||||||
// Mettre à jour la dernière page vue si nécessaire
|
// Mettre à jour la dernière page vue si nécessaire
|
||||||
if ($this->getData(['enrolment', self::$siteContent, $userId, 'lastPageView']) === $this->getUrl(2)) {
|
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
|
// Met à jour la homePage si nécessaire
|
||||||
if ($this->getUrl(2) === $this->getData(['course', self::$siteContent, 'homePageId'])) {
|
if ($this->getUrl(2) === $this->getData(['course', self::$siteContent, 'homePageId'])) {
|
||||||
$this->setData(['course', self::$siteContent, 'homePageId', $pageId]);
|
$this->setData(['course', self::$siteContent, 'homePageId', $pageId]);
|
||||||
@ -383,7 +440,7 @@ class page extends common
|
|||||||
|
|
||||||
// Si la page correspond à la page d'accueil, change l'id dans la configuration du site
|
// Si la page correspond à la page d'accueil, change l'id dans la configuration du site
|
||||||
if ($this->getData(['config', 'homePageId']) === $this->getUrl(2)) {
|
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
|
// Supprime les données du module en cas de changement de module
|
||||||
@ -399,20 +456,22 @@ class page extends common
|
|||||||
}
|
}
|
||||||
// Traitement des pages spéciales affectées dans la config :
|
// Traitement des pages spéciales affectées dans la config :
|
||||||
if ($this->getUrl(2) === $this->getData(['config', 'legalPageId'])) {
|
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'])) {
|
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'])) {
|
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'])) {
|
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'])) {
|
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
|
// Si la page est une page enfant, actualise les positions des autres enfants du parent, sinon actualise les pages sans parents
|
||||||
$lastPosition = 1;
|
$lastPosition = 1;
|
||||||
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
|
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
|
||||||
@ -431,11 +490,12 @@ class page extends common
|
|||||||
$lastPosition++;
|
$lastPosition++;
|
||||||
}
|
}
|
||||||
// Change la position
|
// Change la position
|
||||||
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition]);
|
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition], false);
|
||||||
// Incrémente pour la prochaine position
|
// Incrémente pour la prochaine position
|
||||||
$lastPosition++;
|
$lastPosition++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getinput('pageEditBlock') !== 'bar') {
|
if ($this->getinput('pageEditBlock') !== 'bar') {
|
||||||
$barLeft = $this->getinput('pageEditBarLeft');
|
$barLeft = $this->getinput('pageEditBarLeft');
|
||||||
$barRight = $this->getinput('pageEditBarRight');
|
$barRight = $this->getinput('pageEditBarRight');
|
||||||
@ -456,7 +516,7 @@ class page extends common
|
|||||||
) {
|
) {
|
||||||
foreach ($this->getHierarchy($pageId) as $parentId => $childId) {
|
foreach ($this->getHierarchy($pageId) as $parentId => $childId) {
|
||||||
if ($this->getData(['page', $childId, 'parentPageId']) === $pageId) {
|
if ($this->getData(['page', $childId, 'parentPageId']) === $pageId) {
|
||||||
$this->setData(['page', $childId, 'position', 0]);
|
$this->setData(['page', $childId, 'position', 0], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,17 +525,17 @@ class page extends common
|
|||||||
if ($this->getinput('pageEditBlock') === 'bar') {
|
if ($this->getinput('pageEditBlock') === 'bar') {
|
||||||
foreach ($this->getHierarchy() as $eachPageId => $parentId) {
|
foreach ($this->getHierarchy() as $eachPageId => $parentId) {
|
||||||
if ($this->getData(['page', $eachPageId, 'barRight']) === $this->getUrl(2)) {
|
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)) {
|
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) {
|
foreach ($parentId as $childId) {
|
||||||
if ($this->getData(['page', $childId, 'barRight']) === $this->getUrl(2)) {
|
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)) {
|
if ($this->getData(['page', $childId, 'barLeft']) === $this->getUrl(2)) {
|
||||||
$this->setData(['page', $childId, 'barLeft', $pageId]);
|
$this->setData(['page', $childId, 'barLeft', $pageId], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,7 +694,7 @@ class page extends common
|
|||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'notification' => helper::translate('Modifications enregistrées'),
|
'notification' => helper::translate('Modifications enregistrées'),
|
||||||
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
|
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'state' => true
|
'state' => true
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -669,7 +729,7 @@ class page extends common
|
|||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'notification' => helper::translate('Modifications enregistrées'),
|
'notification' => helper::translate('Modifications enregistrées'),
|
||||||
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
|
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'state' => true
|
'state' => true
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -685,7 +745,7 @@ class page extends common
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne les informations sur les pages en omettant les clés CSS et JS qui occasionnent des bugs d'affichage dans l'éditeur de page
|
* Retourne les informations sur les pages en omettant les clés CSS et JS qui occasionnent des bugs d'affichage dans l'éditeur de page
|
||||||
* @return array tableau associatif des pages dans le menu
|
* @return string tableau associatif des pages dans le menu
|
||||||
*/
|
*/
|
||||||
public function getPageInfo()
|
public function getPageInfo()
|
||||||
{
|
{
|
||||||
@ -695,6 +755,27 @@ class page extends common
|
|||||||
return $d;
|
return $d;
|
||||||
}, $p);
|
}, $p);
|
||||||
return json_encode($d);
|
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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,7 +3,7 @@
|
|||||||
<div class="col1">
|
<div class="col1">
|
||||||
<?php echo template::button('pageCssEditorBack', [
|
<?php echo template::button('pageCssEditorBack', [
|
||||||
'class' => 'buttonGrey',
|
'class' => 'buttonGrey',
|
||||||
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,16 +67,18 @@ $( document ).ready(function() {
|
|||||||
/**
|
/**
|
||||||
* Sélection des onglets
|
* Sélection des onglets
|
||||||
*/
|
*/
|
||||||
var pageLayout = getCookie("pageLayout");
|
var pageLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'page']);?>";
|
||||||
if (pageLayout == null) {
|
// Non défini, valeur par défaut
|
||||||
pageLayout = "content";
|
if (pageLayout == "") {
|
||||||
setCookie("pageLayout", "content");
|
pageLayout = "content";
|
||||||
}
|
}
|
||||||
|
// Tout cacher
|
||||||
$("#pageEditContentContainer").hide();
|
$("#pageEditContentContainer").hide();
|
||||||
$("#pageEditExtensionContainer").hide();
|
$("#pageEditExtensionContainer").hide();
|
||||||
$("#pageEditPositionContainer").hide();
|
$("#pageEditPositionContainer").hide();
|
||||||
$("#pageEditLayoutContainer").hide();
|
$("#pageEditLayoutContainer").hide();
|
||||||
$("#pageEditPermissionContainer").hide();
|
$("#pageEditPermissionContainer").hide();
|
||||||
|
// Afficher la bonne tab
|
||||||
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Container").show();
|
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Container").show();
|
||||||
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Button").addClass("activeButton");
|
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Button").addClass("activeButton");
|
||||||
|
|
||||||
@ -295,7 +297,6 @@ $( document ).ready(function() {
|
|||||||
$("#PageEditPositionButton").removeClass("activeButton");
|
$("#PageEditPositionButton").removeClass("activeButton");
|
||||||
$("#pageEditLayoutButton").removeClass("activeButton");
|
$("#pageEditLayoutButton").removeClass("activeButton");
|
||||||
$("#pageEditPermissionButton").removeClass("activeButton");
|
$("#pageEditPermissionButton").removeClass("activeButton");
|
||||||
setCookie("pageLayout", "content");
|
|
||||||
});
|
});
|
||||||
$("#pageEditExtensionButton").on("click", function () {
|
$("#pageEditExtensionButton").on("click", function () {
|
||||||
$("#pageEditContentContainer").hide();
|
$("#pageEditContentContainer").hide();
|
||||||
@ -308,7 +309,6 @@ $( document ).ready(function() {
|
|||||||
$("#PageEditPositionButton").removeClass("activeButton");
|
$("#PageEditPositionButton").removeClass("activeButton");
|
||||||
$("#pageEditLayoutButton").removeClass("activeButton");
|
$("#pageEditLayoutButton").removeClass("activeButton");
|
||||||
$("#pageEditPermissionButton").removeClass("activeButton");
|
$("#pageEditPermissionButton").removeClass("activeButton");
|
||||||
setCookie("pageLayout", "extension");
|
|
||||||
});
|
});
|
||||||
$("#PageEditPositionButton").on("click", function () {
|
$("#PageEditPositionButton").on("click", function () {
|
||||||
$("#pageEditContentContainer").hide();
|
$("#pageEditContentContainer").hide();
|
||||||
@ -321,7 +321,6 @@ $( document ).ready(function() {
|
|||||||
$("#PageEditPositionButton").addClass("activeButton");
|
$("#PageEditPositionButton").addClass("activeButton");
|
||||||
$("#pageEditLayoutButton").removeClass("activeButton");
|
$("#pageEditLayoutButton").removeClass("activeButton");
|
||||||
$("#pageEditPermissionButton").removeClass("activeButton");
|
$("#pageEditPermissionButton").removeClass("activeButton");
|
||||||
setCookie("pageLayout", "position");
|
|
||||||
});
|
});
|
||||||
$("#pageEditLayoutButton").on("click", function () {
|
$("#pageEditLayoutButton").on("click", function () {
|
||||||
$("#pageEditContentContainer").hide();
|
$("#pageEditContentContainer").hide();
|
||||||
@ -334,7 +333,6 @@ $( document ).ready(function() {
|
|||||||
$("#PageEditPositionButton").removeClass("activeButton");
|
$("#PageEditPositionButton").removeClass("activeButton");
|
||||||
$("#pageEditLayoutButton").addClass("activeButton");
|
$("#pageEditLayoutButton").addClass("activeButton");
|
||||||
$("#pageEditPermissionButton").removeClass("activeButton");
|
$("#pageEditPermissionButton").removeClass("activeButton");
|
||||||
setCookie("pageLayout", "layout");
|
|
||||||
});
|
});
|
||||||
$("#pageEditPermissionButton").on("click", function () {
|
$("#pageEditPermissionButton").on("click", function () {
|
||||||
$("#pageEditContentContainer").hide();
|
$("#pageEditContentContainer").hide();
|
||||||
@ -347,7 +345,6 @@ $( document ).ready(function() {
|
|||||||
$("#pageEditPositionButton").removeClass("activeButton");
|
$("#pageEditPositionButton").removeClass("activeButton");
|
||||||
$("#pageEditLayoutButton").removeClass("activeButton");
|
$("#pageEditLayoutButton").removeClass("activeButton");
|
||||||
$("#pageEditPermissionButton").addClass("activeButton");
|
$("#pageEditPermissionButton").addClass("activeButton");
|
||||||
setCookie("pageLayout", "permission");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -722,30 +719,6 @@ function buildPagesList(extraPosition) {
|
|||||||
positionDOM.val(positionSelected);
|
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
|
// Define function to capitalize the first letter of a string
|
||||||
function capitalizeFirstLetter(string) {
|
function capitalizeFirstLetter(string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<?php echo template::formOpen('pageEditForm'); ?>
|
<?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="row">
|
||||||
<div class="col1">
|
<div class="col1">
|
||||||
<?php echo template::button('configModulesBack', [
|
<?php echo template::button('configModulesBack', [
|
||||||
@ -7,26 +9,17 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col1 offset7">
|
||||||
<?php /**echo template::button('pageEditHelp', [
|
|
||||||
'href' => 'https://doc.zwiicms.fr/edition-des-pages',
|
|
||||||
'target' => '_blank',
|
|
||||||
'value' => template::ico('help'),
|
|
||||||
'class' => 'buttonHelp',
|
|
||||||
'help' => 'Consulter l\'aide en ligne'
|
|
||||||
]); */?>
|
|
||||||
</div>
|
|
||||||
<div class="col1 offset6">
|
|
||||||
<?php echo template::button('pageEditDelete', [
|
<?php echo template::button('pageEditDelete', [
|
||||||
'class' => 'buttonRed',
|
'class' => 'buttonRed',
|
||||||
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'value' => template::ico('trash'),
|
'value' => template::ico('trash'),
|
||||||
'help' => 'Effacer la page'
|
'help' => 'Effacer la page'
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col1">
|
||||||
<?php echo template::button('pageEditDuplicate', [
|
<?php echo template::button('pageEditDuplicate', [
|
||||||
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'value' => template::ico('clone'),
|
'value' => template::ico('clone'),
|
||||||
'help' => 'Dupliquer la page'
|
'help' => 'Dupliquer la page'
|
||||||
]); ?>
|
]); ?>
|
||||||
@ -41,23 +34,28 @@
|
|||||||
<div class="tab">
|
<div class="tab">
|
||||||
<?php echo template::button('pageEditContentButton', [
|
<?php echo template::button('pageEditContentButton', [
|
||||||
'value' => 'Contenu',
|
'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',
|
'value' => 'Menu',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'page/register/position/' . $this->geturl(2)
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php echo template::button('pageEditExtensionButton', [
|
<?php echo template::button('pageEditExtensionButton', [
|
||||||
'value' => 'Extension',
|
'value' => 'Extension',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'page/register/extension/' . $this->geturl(2)
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php echo template::button('pageEditLayoutButton', [
|
<?php echo template::button('pageEditLayoutButton', [
|
||||||
'value' => 'Mise en page',
|
'value' => 'Mise en page',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'page/register/layout/' . $this->geturl(2)
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php echo template::button('pageEditPermissionButton', [
|
<?php echo template::button('pageEditPermissionButton', [
|
||||||
'value' => 'Permission',
|
'value' => 'Permission',
|
||||||
'class' => 'buttonTab'
|
'class' => 'buttonTab',
|
||||||
|
'href' => helper::baseUrl() . 'page/register/permission/' . $this->geturl(2)
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -67,11 +65,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Titres'); ?>
|
<?php echo helper::translate('Titres'); ?>
|
||||||
<!--<span id="infoHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/informations-generales" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col8">
|
<div class="col8">
|
||||||
@ -120,11 +113,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Emplacement dans le menu'); ?>
|
<?php echo helper::translate('Emplacement dans le menu'); ?>
|
||||||
<!--<span id="positionHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/emplacement-dans-le-menu" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="blockContainer">
|
<div class="blockContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -176,11 +164,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Options avancées'); ?>
|
<?php echo helper::translate('Options avancées'); ?>
|
||||||
<!--<span id="advancedHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/options-d-emplacement-avancee" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="blockContainer">
|
<div class="blockContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -195,7 +178,8 @@
|
|||||||
'help' => 'Sélectionnez une image ou une icône de petite dimension',
|
'help' => 'Sélectionnez une image ou une icône de petite dimension',
|
||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'label' => 'Icône',
|
'label' => 'Icône',
|
||||||
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
|
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl']),
|
||||||
|
'folder' => $this->getData(['page', $this->getUrl(2), 'iconUrl']) ? dirname($this->getData(['page', $this->getUrl(2), 'iconUrl'])) : '',
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -292,11 +276,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Mise en page'); ?>
|
<?php echo helper::translate('Mise en page'); ?>
|
||||||
<!--<span id="layoutHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/mise-en-page-2" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="blockContainer">
|
<div class="blockContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -372,11 +351,6 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<h4>
|
<h4>
|
||||||
<?php echo helper::translate('Permission et référencement'); ?>
|
<?php echo helper::translate('Permission et référencement'); ?>
|
||||||
<!--<span id="seoHelpButton" class="helpDisplayButton">
|
|
||||||
<a href="https://doc.zwiicms.fr/permission-et-referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
|
|
||||||
<?php //echo template::ico('help', ['margin' => 'left']); ?>
|
|
||||||
</a>
|
|
||||||
</span>-->
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="blockContainer">
|
<div class="blockContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -424,5 +398,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php echo template::formClose(); ?>
|
<?php echo template::formClose(); ?>
|
@ -3,7 +3,7 @@
|
|||||||
<div class="col1">
|
<div class="col1">
|
||||||
<?php echo template::button('pageJsEditorBack', [
|
<?php echo template::button('pageJsEditorBack', [
|
||||||
'class' => 'buttonGrey',
|
'class' => 'buttonGrey',
|
||||||
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
|
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
|
||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,7 +25,7 @@ class plugin extends common
|
|||||||
'delete' => self::GROUP_ADMIN,
|
'delete' => self::GROUP_ADMIN,
|
||||||
'save' => self::GROUP_ADMIN,
|
'save' => self::GROUP_ADMIN,
|
||||||
'store' => self::GROUP_ADMIN,
|
'store' => self::GROUP_ADMIN,
|
||||||
'item' => self::GROUP_ADMIN,
|
//'item' => self::GROUP_ADMIN,
|
||||||
// détail d'un objet
|
// détail d'un objet
|
||||||
'upload' => self::GROUP_ADMIN,
|
'upload' => self::GROUP_ADMIN,
|
||||||
// Téléverser catalogue
|
// Téléverser catalogue
|
||||||
@ -237,8 +237,8 @@ class plugin extends common
|
|||||||
return ([
|
return ([
|
||||||
'success' => $success,
|
'success' => $success,
|
||||||
'notification' => $success
|
'notification' => $success
|
||||||
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
|
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
|
||||||
: helper::translate('Erreur inconnue, le module n\'est pas installé')
|
: helper::translate('Erreur inconnue, le module n\'est pas installé')
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
// Supprimer le dossier temporaire
|
// Supprimer le dossier temporaire
|
||||||
@ -391,7 +391,6 @@ class plugin extends common
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => helper::translate('Catalogue de modules'),
|
'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
|
* 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
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'title' => helper::translate('Gestion des modules'),
|
'title' => helper::translate('Gestion des modules'),
|
||||||
|
@ -507,21 +507,23 @@ class theme extends common
|
|||||||
'featureContent' => $featureContent,
|
'featureContent' => $featureContent,
|
||||||
'featureFiles' => $files
|
'featureFiles' => $files
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
// Modification de la position du menu selon la position de la bannière
|
// Modification de la position du menu selon la position de la bannière
|
||||||
if ($this->getData(['theme', 'header', 'position']) == 'site') {
|
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') {
|
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
|
// Menu accroché à la bannière qui devient cachée
|
||||||
if (
|
if (
|
||||||
$this->getData(['theme', 'header', 'position']) == 'hide' &&
|
$this->getData(['theme', 'header', 'position']) == 'hide' &&
|
||||||
in_array($this->getData(['theme', 'menu', 'position']), ['body-first', 'site-first', 'body-first', 'site-second'])
|
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
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'notification' => helper::translate('Modifications enregistrées'),
|
'notification' => helper::translate('Modifications enregistrées'),
|
||||||
@ -636,11 +638,11 @@ class theme extends common
|
|||||||
// Polices liées aux thèmes des espaces
|
// Polices liées aux thèmes des espaces
|
||||||
foreach ($this->getData(['course']) as $courseId => $courseValue) {
|
foreach ($this->getData(['course']) as $courseId => $courseValue) {
|
||||||
$theme = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/theme.json'), true);
|
$theme = json_decode(file_get_contents(self::DATA_DIR . $courseId . '/theme.json'), true);
|
||||||
$fonts['Bannière ('. $courseId .')'] = $theme['theme']['header']['font'];
|
$fonts['Bannière (' . $courseId . ')'] = $theme['theme']['header']['font'];
|
||||||
$fonts['Menu ('. $courseId .')'] = $theme['theme']['menu']['font'];
|
$fonts['Menu (' . $courseId . ')'] = $theme['theme']['menu']['font'];
|
||||||
$fonts['Titre ('. $courseId .')'] = $theme['theme']['title']['font'];
|
$fonts['Titre (' . $courseId . ')'] = $theme['theme']['title']['font'];
|
||||||
$fonts['Texte ('. $courseId .')'] = $theme['theme']['text']['font'];
|
$fonts['Texte (' . $courseId . ')'] = $theme['theme']['text']['font'];
|
||||||
$fonts['Pied de page ('. $courseId .')'] = $theme['theme']['footer']['font'];
|
$fonts['Pied de page (' . $courseId . ')'] = $theme['theme']['footer']['font'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer le détail des fontes installées
|
// Récupérer le détail des fontes installées
|
||||||
@ -658,7 +660,7 @@ class theme extends common
|
|||||||
if (is_array($typeValue)) {
|
if (is_array($typeValue)) {
|
||||||
foreach ($typeValue as $fontId => $fontValue) {
|
foreach ($typeValue as $fontId => $fontValue) {
|
||||||
// Recherche les correspondances
|
// Recherche les correspondances
|
||||||
$result = array_filter($fonts, function($value) use ($fontId) {
|
$result = array_filter($fonts, function ($value) use ($fontId) {
|
||||||
return $value == $fontId;
|
return $value == $fontId;
|
||||||
});
|
});
|
||||||
$keyResults = array_keys($result);
|
$keyResults = array_keys($result);
|
||||||
@ -929,7 +931,7 @@ class theme extends common
|
|||||||
'fontWeight' => $this->getInput('themeTitleFontWeight'),
|
'fontWeight' => $this->getInput('themeTitleFontWeight'),
|
||||||
'textTransform' => $this->getInput('themeTitleTextTransform')
|
'textTransform' => $this->getInput('themeTitleTextTransform')
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'theme',
|
'theme',
|
||||||
'text',
|
'text',
|
||||||
@ -939,7 +941,7 @@ class theme extends common
|
|||||||
'textColor' => $this->getInput('themeTextTextColor'),
|
'textColor' => $this->getInput('themeTextTextColor'),
|
||||||
'linkColor' => $this->getInput('themeTextLinkColor')
|
'linkColor' => $this->getInput('themeTextLinkColor')
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'theme',
|
'theme',
|
||||||
'site',
|
'site',
|
||||||
@ -950,14 +952,14 @@ class theme extends common
|
|||||||
'width' => $this->getInput('themeSiteWidth'),
|
'width' => $this->getInput('themeSiteWidth'),
|
||||||
'margin' => $this->getInput('themeSiteMargin', helper::FILTER_BOOLEAN)
|
'margin' => $this->getInput('themeSiteMargin', helper::FILTER_BOOLEAN)
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'theme',
|
'theme',
|
||||||
'button',
|
'button',
|
||||||
[
|
[
|
||||||
'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
|
'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'theme',
|
'theme',
|
||||||
'block',
|
'block',
|
||||||
|
@ -7,15 +7,7 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2 offset9">
|
||||||
<?php /* echo template::button('themeBodyHelp', [
|
|
||||||
'href' => 'https://doc.zwiicms.fr/arriere-plan',
|
|
||||||
'target' => '_blank',
|
|
||||||
'value' => template::ico('help'),
|
|
||||||
'class' => 'buttonHelp'
|
|
||||||
]); */ ?>
|
|
||||||
</div>
|
|
||||||
<div class="col2 offset8">
|
|
||||||
<?php echo template::submit('themeBodySubmit'); ?>
|
<?php echo template::submit('themeBodySubmit'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col6">
|
||||||
<?php echo template::text('themeBodyToTopColor', [
|
<?php echo template::text('themeBodyToTopColor', [
|
||||||
'class' => 'colorPicker',
|
'class' => 'colorPicker',
|
||||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||||
'label' => 'Couleur icône haut de page',
|
'label' => 'Couleur icône haut de page',
|
||||||
@ -68,7 +60,8 @@
|
|||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'label' => 'Arrière plan',
|
'label' => 'Arrière plan',
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
'value' => $imageFile
|
'value' => $imageFile,
|
||||||
|
'folder' => $imageFile ? dirname($imageFile) : ''
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +20,7 @@ $('#dataTables').DataTable({
|
|||||||
},
|
},
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
|
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
|
||||||
"columnDefs": [{
|
"columnDefs": [{
|
||||||
target: 5,
|
target: 5,
|
||||||
orderable: false,
|
orderable: false,
|
||||||
|
@ -7,15 +7,7 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2 offset9">
|
||||||
<?php /* echo template::button('themeHeaderHelp', [
|
|
||||||
'href' => 'https://doc.zwiicms.fr/banniere',
|
|
||||||
'target' => '_blank',
|
|
||||||
'value' => template::ico('help'),
|
|
||||||
'class' => 'buttonHelp'
|
|
||||||
]); */?>
|
|
||||||
</div>
|
|
||||||
<div class="col2 offset8">
|
|
||||||
<?php echo template::submit('themeHeaderSubmit'); ?>
|
<?php echo template::submit('themeHeaderSubmit'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -158,13 +150,17 @@
|
|||||||
'label' => 'Image',
|
'label' => 'Image',
|
||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
'value' => $imageFile
|
'value' => $imageFile,
|
||||||
|
'folder' => $imageFile ? dirname($imageFile) : ''
|
||||||
]);
|
]);
|
||||||
?>
|
?>
|
||||||
<span class="themeHeaderImageOptions displayNone" id="themeHeaderImageInfo">
|
<span class="themeHeaderImageOptions displayNone" id="themeHeaderImageInfo">
|
||||||
<?php echo helper::translate('Largeur de l\'image'); ?> <span id="themeHeaderImageWidth"></span> ; <?php echo helper::translate('Largeur du site :'); ?> <?php echo $this->getData(['theme', 'site', 'width']); ?>
|
<?php echo helper::translate('Largeur de l\'image'); ?> <span id="themeHeaderImageWidth"></span>
|
||||||
|
; <?php echo helper::translate('Largeur du site :'); ?>
|
||||||
|
<?php echo $this->getData(['theme', 'site', 'width']); ?>
|
||||||
|
|
|
|
||||||
<?php echo helper::translate('Hauteur de l\'image'); ?> <span id="themeHeaderImageHeight"></span>
|
<?php echo helper::translate('Hauteur de l\'image'); ?> <span
|
||||||
|
id="themeHeaderImageHeight"></span>
|
||||||
|
|
|
|
||||||
<?php echo helper::translate('Ratio'); ?> <span id="themeHeaderImageRatio"></span>
|
<?php echo helper::translate('Ratio'); ?> <span id="themeHeaderImageRatio"></span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -7,15 +7,7 @@
|
|||||||
'value' => template::ico('left')
|
'value' => template::ico('left')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2 offset9">
|
||||||
<?php /* echo template::button('themeMenuHelp', [
|
|
||||||
'href' => 'https://doc.zwiicms.fr/menu',
|
|
||||||
'target' => '_blank',
|
|
||||||
'value' => template::ico('help'),
|
|
||||||
'class' => 'buttonHelp'
|
|
||||||
]); */?>
|
|
||||||
</div>
|
|
||||||
<div class="col2 offset8">
|
|
||||||
<?php echo template::submit('themeMenuSubmit'); ?>
|
<?php echo template::submit('themeMenuSubmit'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -112,117 +104,117 @@
|
|||||||
'selected' => $this->getData(['theme', 'menu', 'burgerContent']),
|
'selected' => $this->getData(['theme', 'menu', 'burgerContent']),
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col6" id="themeMenuBurgerLogoId"
|
<div class="col6" id="themeMenuBurgerLogoId" class="<?php if ($this->getData(['theme', 'menu', 'burgerContent']) !== 'logo')
|
||||||
class="<?php if ($this->getData(['theme', 'menu', 'burgerContent']) !== 'logo')
|
echo 'displayNone'; ?>">
|
||||||
echo 'displayNone'; ?>">
|
<?php $imageFile = file_exists(self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo'])) ? $this->getData(['theme', 'menu', 'burgerLogo']) : ""; ?>
|
||||||
<?php $imageFile = file_exists(self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo'])) ? $this->getData(['theme', 'menu', 'burgerLogo']) : ""; ?>
|
<?php echo template::file('themeMenuBurgerLogo', [
|
||||||
<?php echo template::file('themeMenuBurgerLogo', [
|
'help' => 'Sélectionner une image de dimensions adaptées',
|
||||||
'help' => 'Sélectionner une image de dimensions adaptées',
|
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
||||||
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
|
'label' => 'Logo du menu burger',
|
||||||
'label' => 'Logo du menu burger',
|
'type' => 1,
|
||||||
'type' => 1,
|
'value' => $imageFile,
|
||||||
'value' => $imageFile
|
'folder' => $imageFile ? dirname($imageFile) : ''
|
||||||
]);
|
]);
|
||||||
?>
|
?>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<div class="col12">
|
<div class="row">
|
||||||
<div class="block">
|
<div class="col12">
|
||||||
<h4>
|
<div class="block">
|
||||||
<?php echo helper::translate('Couleurs'); ?>
|
<h4>
|
||||||
</h4>
|
<?php echo helper::translate('Couleurs'); ?>
|
||||||
<div class="row">
|
</h4>
|
||||||
<div class="col4">
|
<div class="row">
|
||||||
<?php echo template::text('themeMenuTextColor', [
|
<div class="col4">
|
||||||
'class' => 'colorPicker',
|
<?php echo template::text('themeMenuTextColor', [
|
||||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
'class' => 'colorPicker',
|
||||||
'label' => 'Texte',
|
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||||
'value' => $this->getData(['theme', 'menu', 'textColor'])
|
'label' => 'Texte',
|
||||||
]); ?>
|
'value' => $this->getData(['theme', 'menu', 'textColor'])
|
||||||
</div>
|
]); ?>
|
||||||
<div class="col4">
|
|
||||||
<?php echo template::text('themeMenuBackgroundColor', [
|
|
||||||
'class' => 'colorPicker',
|
|
||||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
|
||||||
'label' => 'Arrière plan',
|
|
||||||
'value' => $this->getData(['theme', 'menu', 'backgroundColor'])
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col4">
|
|
||||||
<?php echo template::text('themeMenuBackgroundColorSub', [
|
|
||||||
'class' => 'colorPicker',
|
|
||||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
|
||||||
'label' => 'Fond du sous-menu',
|
|
||||||
'value' => $this->getData(['theme', 'menu', 'backgroundColorSub'])
|
|
||||||
]); ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="col4">
|
||||||
<div class="col4">
|
<?php echo template::text('themeMenuBackgroundColor', [
|
||||||
<?php echo template::text('themeMenuActiveTextColor', [
|
'class' => 'colorPicker',
|
||||||
'class' => 'colorPicker',
|
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
'label' => 'Arrière plan',
|
||||||
'label' => 'Couleur texte page active',
|
'value' => $this->getData(['theme', 'menu', 'backgroundColor'])
|
||||||
'value' => $this->getData(['theme', 'menu', 'activeTextColor'])
|
]); ?>
|
||||||
]); ?>
|
</div>
|
||||||
</div>
|
<div class="col4">
|
||||||
<div class="col4 verticalAlignBottom">
|
<?php echo template::text('themeMenuBackgroundColorSub', [
|
||||||
<?php
|
'class' => 'colorPicker',
|
||||||
echo template::checkbox('themeMenuActiveColorAuto', true, 'Couleur de fond automatique', [
|
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||||
'checked' => $this->getData(['theme', 'menu', 'activeColorAuto']),
|
'label' => 'Fond du sous-menu',
|
||||||
]); ?>
|
'value' => $this->getData(['theme', 'menu', 'backgroundColorSub'])
|
||||||
</div>
|
]); ?>
|
||||||
<div class="col4">
|
</div>
|
||||||
<?php echo template::text('themeMenuActiveColor', [
|
</div>
|
||||||
'class' => 'colorPicker',
|
<div class="row">
|
||||||
'help' => 'Couleur de fond de la page sélectionnée dans le menu.<br>Le curseur horizontal règle le niveau de transparence.',
|
<div class="col4">
|
||||||
'label' => 'Fond page active',
|
<?php echo template::text('themeMenuActiveTextColor', [
|
||||||
'value' => $this->getData(['theme', 'menu', 'activeColor'])
|
'class' => 'colorPicker',
|
||||||
]); ?>
|
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||||
</div>
|
'label' => 'Couleur texte page active',
|
||||||
|
'value' => $this->getData(['theme', 'menu', 'activeTextColor'])
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col4 verticalAlignBottom">
|
||||||
|
<?php
|
||||||
|
echo template::checkbox('themeMenuActiveColorAuto', true, 'Couleur de fond automatique', [
|
||||||
|
'checked' => $this->getData(['theme', 'menu', 'activeColorAuto']),
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col4">
|
||||||
|
<?php echo template::text('themeMenuActiveColor', [
|
||||||
|
'class' => 'colorPicker',
|
||||||
|
'help' => 'Couleur de fond de la page sélectionnée dans le menu.<br>Le curseur horizontal règle le niveau de transparence.',
|
||||||
|
'label' => 'Fond page active',
|
||||||
|
'value' => $this->getData(['theme', 'menu', 'activeColor'])
|
||||||
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<div class="col12">
|
<div class="row">
|
||||||
<div class="block">
|
<div class="col12">
|
||||||
<h4>
|
<div class="block">
|
||||||
<?php echo helper::translate('Mise en forme du texte'); ?>
|
<h4>
|
||||||
</h4>
|
<?php echo helper::translate('Mise en forme du texte'); ?>
|
||||||
<div class="row">
|
</h4>
|
||||||
<div class="col3">
|
<div class="row">
|
||||||
<?php echo template::select('themeMenuFont', $module::$fonts['name'], [
|
<div class="col3">
|
||||||
'label' => 'Fonte',
|
<?php echo template::select('themeMenuFont', $module::$fonts['name'], [
|
||||||
'selected' => $this->getData(['theme', 'menu', 'font']),
|
'label' => 'Fonte',
|
||||||
'font' => $module::$fonts['family']
|
'selected' => $this->getData(['theme', 'menu', 'font']),
|
||||||
]); ?>
|
'font' => $module::$fonts['family']
|
||||||
</div>
|
]); ?>
|
||||||
<div class="col3">
|
</div>
|
||||||
<?php echo template::select('themeMenuFontSize', $module::$menuFontSizes, [
|
<div class="col3">
|
||||||
'label' => 'Taille',
|
<?php echo template::select('themeMenuFontSize', $module::$menuFontSizes, [
|
||||||
'help' => 'Proportionnelle à la taille définie dans le site.',
|
'label' => 'Taille',
|
||||||
'selected' => $this->getData(['theme', 'menu', 'fontSize'])
|
'help' => 'Proportionnelle à la taille définie dans le site.',
|
||||||
]); ?>
|
'selected' => $this->getData(['theme', 'menu', 'fontSize'])
|
||||||
</div>
|
]); ?>
|
||||||
<div class="col3">
|
</div>
|
||||||
<?php echo template::select('themeMenuFontWeight', $module::$fontWeights, [
|
<div class="col3">
|
||||||
'label' => 'Style',
|
<?php echo template::select('themeMenuFontWeight', $module::$fontWeights, [
|
||||||
'selected' => $this->getData(['theme', 'menu', 'fontWeight'])
|
'label' => 'Style',
|
||||||
]); ?>
|
'selected' => $this->getData(['theme', 'menu', 'fontWeight'])
|
||||||
</div>
|
]); ?>
|
||||||
<div class="col3">
|
</div>
|
||||||
<?php echo template::select('themeMenuTextTransform', $module::$textTransforms, [
|
<div class="col3">
|
||||||
'label' => 'Casse',
|
<?php echo template::select('themeMenuTextTransform', $module::$textTransforms, [
|
||||||
'selected' => $this->getData(['theme', 'menu', 'textTransform'])
|
'label' => 'Casse',
|
||||||
]); ?>
|
'selected' => $this->getData(['theme', 'menu', 'textTransform'])
|
||||||
</div>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php echo template::formClose(); ?>
|
</div>
|
||||||
|
<?php echo template::formClose(); ?>
|
@ -19,6 +19,7 @@ class user extends common
|
|||||||
public static $actions = [
|
public static $actions = [
|
||||||
'add' => self::GROUP_ADMIN,
|
'add' => self::GROUP_ADMIN,
|
||||||
'delete' => self::GROUP_ADMIN,
|
'delete' => self::GROUP_ADMIN,
|
||||||
|
'usersDelete' => self::GROUP_ADMIN,
|
||||||
'import' => self::GROUP_ADMIN,
|
'import' => self::GROUP_ADMIN,
|
||||||
'index' => self::GROUP_ADMIN,
|
'index' => self::GROUP_ADMIN,
|
||||||
'template' => self::GROUP_ADMIN,
|
'template' => self::GROUP_ADMIN,
|
||||||
@ -31,6 +32,7 @@ class user extends common
|
|||||||
'profilEdit' => self::GROUP_ADMIN,
|
'profilEdit' => self::GROUP_ADMIN,
|
||||||
'profilAdd' => self::GROUP_ADMIN,
|
'profilAdd' => self::GROUP_ADMIN,
|
||||||
'profilDelete' => self::GROUP_ADMIN,
|
'profilDelete' => self::GROUP_ADMIN,
|
||||||
|
'tag' => self::GROUP_ADMIN,
|
||||||
];
|
];
|
||||||
|
|
||||||
public static $users = [];
|
public static $users = [];
|
||||||
@ -229,6 +231,161 @@ class user extends common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Désinscription de tous les utilisateurs
|
||||||
|
* Les désinscriptions ne suppriment pas les historiques
|
||||||
|
*/
|
||||||
|
public function usersDelete()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Contenu sélectionné
|
||||||
|
$courseId = $this->getUrl(2);
|
||||||
|
|
||||||
|
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
|
||||||
|
if (
|
||||||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
|
) {
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'access' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inscription des utilisateurs cochés
|
||||||
|
if (
|
||||||
|
isset($_POST['usersDeleteSubmit'])
|
||||||
|
) {
|
||||||
|
$notification = helper::translate('Suppression de %s compte');
|
||||||
|
$success = true;
|
||||||
|
$count = 0;
|
||||||
|
foreach ($_POST as $keyPost => $valuePost) {
|
||||||
|
// Exclure les variables post qui ne sont pas des userId et ne traiter que les non inscrits
|
||||||
|
if (
|
||||||
|
$this->getData(['user', $keyPost]) !== null
|
||||||
|
) {
|
||||||
|
|
||||||
|
if ($keyPost === $this->getUser('id')) {
|
||||||
|
$notification = helper::translate('Votre compte n\'a pas été supprimé !') . '<br />' . $notification;
|
||||||
|
$success = 1;
|
||||||
|
} else {
|
||||||
|
$this->deleteData(['user', $keyPost]);
|
||||||
|
$count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'redirect' => helper::baseUrl() . 'user/usersDelete',
|
||||||
|
'notification' => sprintf($count > 1 ? $notification . 's' : $notification, $count),
|
||||||
|
'state' => $success
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste des groupes et des profils
|
||||||
|
$usersGroups = $this->getData(['profil']);
|
||||||
|
|
||||||
|
foreach ($usersGroups as $groupId => $groupValue) {
|
||||||
|
switch ($groupId) {
|
||||||
|
case "-1":
|
||||||
|
case "0":
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
self::$usersGroups['30'] = 'Administrateur';
|
||||||
|
$profils['30'] = 0;
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
case "2":
|
||||||
|
foreach ($groupValue as $profilId => $profilValue) {
|
||||||
|
if ($profilId) {
|
||||||
|
self::$usersGroups[$groupId . $profilId] = sprintf(helper::translate('Groupe %s - Profil %s'), self::$groupPublics[$groupId], $profilValue['name']);
|
||||||
|
$profils[$groupId . $profilId] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste alphabétique
|
||||||
|
self::$alphabet = range('A', 'Z');
|
||||||
|
$alphabet = range('A', 'Z');
|
||||||
|
self::$alphabet = array_combine($alphabet, self::$alphabet);
|
||||||
|
self::$alphabet = array_merge(['all' => 'Tout'], self::$alphabet);
|
||||||
|
|
||||||
|
// Liste des inscrits dans le contenu sélectionné.
|
||||||
|
$users = $this->getData(['user']);
|
||||||
|
if (is_array($users)) {
|
||||||
|
// Tri du tableau par défaut par $userId
|
||||||
|
ksort($users);
|
||||||
|
foreach ($users as $userId => $userValue) {
|
||||||
|
|
||||||
|
// Compte les rôles
|
||||||
|
if (isset($profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])])) {
|
||||||
|
$profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtres
|
||||||
|
if (
|
||||||
|
isset($_POST['usersFilterGroup'])
|
||||||
|
|| isset($_POST['usersFilterFirstName'])
|
||||||
|
|| isset($_POST['usersFilterLastName'])
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Groupe et profils
|
||||||
|
$group = (string) $this->getData(['user', $userId, 'group']);
|
||||||
|
$profil = (string) $this->getData(['user', $userId, 'profil']);
|
||||||
|
$firstName = $this->getData(['user', $userId, 'firstname']);
|
||||||
|
$lastName = $this->getData(['user', $userId, 'lastname']);
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterGroup', helper::FILTER_INT) > 0
|
||||||
|
&& $this->getInput('usersFilterGroup', helper::FILTER_STRING_SHORT) !== $group . $profil
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
// Première lettre du prénom
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterFirstName', helper::FILTER_STRING_SHORT) !== 'all'
|
||||||
|
&& $this->getInput('usersFilterFirstName', helper::FILTER_STRING_SHORT) !== strtoupper(substr($firstName, 0, 1))
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
// Première lettre du nom
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterLastName', helper::FILTER_STRING_SHORT) !== 'all'
|
||||||
|
&& $this->getInput('usersFilterLastName', helper::FILTER_STRING_SHORT) !== strtoupper(substr($lastName, 0, 1))
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construction du tableau
|
||||||
|
self::$users[] = [
|
||||||
|
template::checkbox($userId, true, '', ['class' => 'checkboxSelect']),
|
||||||
|
$userId,
|
||||||
|
$this->getData(['user', $userId, 'firstname']),
|
||||||
|
$this->getData(['user', $userId, 'lastname']),
|
||||||
|
$this->getData(['user', $userId, 'tags']),
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajoute les effectifs aux profils du sélecteur
|
||||||
|
foreach (self::$usersGroups as $groupId => $groupValue) {
|
||||||
|
if ($groupId === 'all') {
|
||||||
|
self::$usersGroups['all'] = self::$usersGroups['all'] . ' (' . array_sum($profils) . ')';
|
||||||
|
} else {
|
||||||
|
self::$usersGroups[$groupId] = self::$usersGroups[$groupId] . ' (' . $profils[$groupId] . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'title' => helper::translate('Désincription en masse'),
|
||||||
|
'view' => 'usersDelete',
|
||||||
|
'vendor' => [
|
||||||
|
'datatables'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Édition
|
* Édition
|
||||||
*/
|
*/
|
||||||
@ -271,7 +428,9 @@ class user extends common
|
|||||||
if ($this->getUser('group') < self::GROUP_ADMIN) {
|
if ($this->getUser('group') < self::GROUP_ADMIN) {
|
||||||
if ($this->getInput('userEditNewPassword')) {
|
if ($this->getInput('userEditNewPassword')) {
|
||||||
// L'ancien mot de passe est correct
|
// 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
|
// La confirmation correspond au mot de passe
|
||||||
if ($this->getInput('userEditNewPassword') === $this->getInput('userEditConfirmPassword')) {
|
if ($this->getInput('userEditNewPassword') === $this->getInput('userEditConfirmPassword')) {
|
||||||
$newPassword = $this->getInput('userEditNewPassword', helper::FILTER_PASSWORD, true);
|
$newPassword = $this->getInput('userEditNewPassword', helper::FILTER_PASSWORD, true);
|
||||||
@ -345,6 +504,7 @@ class user extends common
|
|||||||
'files' => $this->getInput('userEditFiles', helper::FILTER_BOOLEAN),
|
'files' => $this->getInput('userEditFiles', helper::FILTER_BOOLEAN),
|
||||||
'language' => $this->getInput('userEditLanguage', helper::FILTER_STRING_SHORT),
|
'language' => $this->getInput('userEditLanguage', helper::FILTER_STRING_SHORT),
|
||||||
'tags' => $this->getInput('userEditTags', 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
|
// Redirection spécifique si l'utilisateur change son mot de passe
|
||||||
@ -415,7 +575,7 @@ class user extends common
|
|||||||
// Enregistre la date de la demande dans le compte utilisateur
|
// Enregistre la date de la demande dans le compte utilisateur
|
||||||
$this->setData(['user', $userId, 'forgot', time()]);
|
$this->setData(['user', $userId, 'forgot', time()]);
|
||||||
// Crée un id unique pour la réinitialisation
|
// 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
|
// Envoi le mail
|
||||||
$sent = $this->sendMail(
|
$sent = $this->sendMail(
|
||||||
$this->getData(['user', $userId, 'mail']),
|
$this->getData(['user', $userId, 'mail']),
|
||||||
@ -711,12 +871,35 @@ class user extends common
|
|||||||
// Droit d'intervenir sur tous les espaces
|
// Droit d'intervenir sur tous les espaces
|
||||||
'tutor' => $this->getInput('profilEditCourseTutor', helper::FILTER_BOOLEAN),
|
'tutor' => $this->getInput('profilEditCourseTutor', helper::FILTER_BOOLEAN),
|
||||||
// Droit d'accéder à la fenêtre de gestion pour tous les éditeurs et plus
|
// Droit d'accéder à la fenêtre de gestion pour tous les éditeurs et plus
|
||||||
'index' => $this->getUser('group') >= self::GROUP_EDITOR,
|
'index' => $this->getInput('profilEditCourseUsers', helper::FILTER_BOOLEAN)
|
||||||
'manage' => $this->getUser('group') >= self::GROUP_EDITOR,
|
|| $this->getInput('profilEditCourseUserHistory', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCoursExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserAdd', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUsersAdd', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserDelete', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUsersDelete', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseEdit', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseBackup', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseRestore', helper::FILTER_BOOLEAN),
|
||||||
|
|
||||||
|
'manage' => $this->getInput('profilEditCourseUsers', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserHistory', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCoursExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserAdd', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUsersAdd', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUserDelete', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseUsersDelete', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseEdit', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseBackup', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseRestore', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilEditCourseReset', helper::FILTER_BOOLEAN),
|
||||||
// Droits spécifiques
|
// Droits spécifiques
|
||||||
'users' => $this->getInput('profilEditCourseUsers', helper::FILTER_BOOLEAN),
|
'users' => $this->getInput('profilEditCourseUsers', helper::FILTER_BOOLEAN),
|
||||||
'userHistory' => $this->getInput('profilEditCourseUserHistory', 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),
|
'userAdd' => $this->getInput('profilEditCourseUserAdd', helper::FILTER_BOOLEAN),
|
||||||
'usersAdd' => $this->getInput('profilEditCourseUsersAdd', helper::FILTER_BOOLEAN),
|
'usersAdd' => $this->getInput('profilEditCourseUsersAdd', helper::FILTER_BOOLEAN),
|
||||||
'userDelete' => $this->getInput('profilEditCourseUserDelete', helper::FILTER_BOOLEAN),
|
'userDelete' => $this->getInput('profilEditCourseUserDelete', helper::FILTER_BOOLEAN),
|
||||||
@ -724,6 +907,7 @@ class user extends common
|
|||||||
'edit' => $this->getInput('profilEditCourseEdit', helper::FILTER_BOOLEAN),
|
'edit' => $this->getInput('profilEditCourseEdit', helper::FILTER_BOOLEAN),
|
||||||
'backup' => $this->getInput('profilEditCourseBackup', helper::FILTER_BOOLEAN),
|
'backup' => $this->getInput('profilEditCourseBackup', helper::FILTER_BOOLEAN),
|
||||||
'restore' => $this->getInput('profilEditCourseRestore', helper::FILTER_BOOLEAN),
|
'restore' => $this->getInput('profilEditCourseRestore', helper::FILTER_BOOLEAN),
|
||||||
|
'reset' => $this->getInput('profilEditCourseReset', helper::FILTER_BOOLEAN),
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -757,7 +941,7 @@ class user extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Chemin vers les dossiers du gestionnaire de fichier
|
// Chemin vers les dossiers du gestionnaire de fichier
|
||||||
self::$sharePath = $this->getSubdirectories('site/file/source');
|
self::$sharePath = $this->getSubdirectories('site/file/source');
|
||||||
|
|
||||||
// Exclure les espaces des cours
|
// Exclure les espaces des cours
|
||||||
foreach (array_keys($this->getData(['course'])) as $courseId) {
|
foreach (array_keys($this->getData(['course'])) as $courseId) {
|
||||||
@ -888,6 +1072,7 @@ class user extends common
|
|||||||
'index' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN)
|
'index' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserHistory', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserHistory', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserExport', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilAddCoursExport', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN)
|
||||||
@ -895,21 +1080,23 @@ class user extends common
|
|||||||
|| $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN),
|
|| $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN),
|
||||||
|
|
||||||
'manage' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN)
|
'manage' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserHistory', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserHistory', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserExport', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserExport', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilAddCoursExport', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseUsersDelete', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseUsersDelete', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN)
|
|| $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN)
|
||||||
|| $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN),
|
|| $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN)
|
||||||
|
|| $this->getInput('profilAddCourseReset', helper::FILTER_BOOLEAN),
|
||||||
// La suite
|
// La suite
|
||||||
'users' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN),
|
'users' => $this->getInput('profilAddCourseUsers', helper::FILTER_BOOLEAN),
|
||||||
'userHistory' => $this->getInput('profilAddCourseUserHistory', 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),
|
'userAdd' => $this->getInput('profilAddCourseUserAdd', helper::FILTER_BOOLEAN),
|
||||||
'usersAdd' => $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN),
|
'usersAdd' => $this->getInput('profilAddCourseUsersAdd', helper::FILTER_BOOLEAN),
|
||||||
'userDelete' => $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN),
|
'userDelete' => $this->getInput('profilAddCourseUserDelete', helper::FILTER_BOOLEAN),
|
||||||
@ -917,6 +1104,7 @@ class user extends common
|
|||||||
'edit' => $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN),
|
'edit' => $this->getInput('profilAddCourseEdit', helper::FILTER_BOOLEAN),
|
||||||
'backup' => $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN),
|
'backup' => $this->getInput('profilAddCourseBackup', helper::FILTER_BOOLEAN),
|
||||||
'restore' => $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN),
|
'restore' => $this->getInput('profilAddCourseRestore', helper::FILTER_BOOLEAN),
|
||||||
|
'reset' => $this->getInput('profilAddCourseReset', helper::FILTER_BOOLEAN),
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -962,12 +1150,12 @@ class user extends common
|
|||||||
|
|
||||||
// Exclure les espaces des cours
|
// Exclure les espaces des cours
|
||||||
/*
|
/*
|
||||||
foreach (array_keys($this->getData(['course'])) as $courseId) {
|
foreach (array_keys($this->getData(['course'])) as $courseId) {
|
||||||
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
|
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
|
||||||
return strpos($key, $courseId) === false;
|
return strpos($key, $courseId) === false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
self::$sharePath = array_flip(self::$sharePath);
|
self::$sharePath = array_flip(self::$sharePath);
|
||||||
self::$sharePath = array_merge(['none' => 'Aucun Accès'], self::$sharePath);
|
self::$sharePath = array_merge(['none' => 'Aucun Accès'], self::$sharePath);
|
||||||
@ -1074,7 +1262,7 @@ class user extends common
|
|||||||
'lastFail' => time(),
|
'lastFail' => time(),
|
||||||
'ip' => helper::getIp()
|
'ip' => helper::getIp()
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
// Verrouillage des IP
|
// Verrouillage des IP
|
||||||
$ipBlackList = helper::arrayColumn($this->getData(['blacklist']), 'ip');
|
$ipBlackList = helper::arrayColumn($this->getData(['blacklist']), 'ip');
|
||||||
if (
|
if (
|
||||||
@ -1103,8 +1291,8 @@ class user extends common
|
|||||||
$this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
|
$this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
|
||||||
and $this->getData(['user', $userId, 'connectFail']) === $this->getData(['config', 'connect', 'attempt'])
|
and $this->getData(['user', $userId, 'connectFail']) === $this->getData(['config', 'connect', 'attempt'])
|
||||||
) {
|
) {
|
||||||
$this->setData(['user', $userId, 'connectFail', 0]);
|
$this->setData(['user', $userId, 'connectFail', 0], false);
|
||||||
$this->setData(['user', $userId, 'connectTimeout', 0]);
|
$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
|
// 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
|
// Vérification du mot de passe et du groupe
|
||||||
@ -1116,14 +1304,36 @@ class user extends common
|
|||||||
and $captcha === true
|
and $captcha === true
|
||||||
) {
|
) {
|
||||||
// RAZ
|
// RAZ
|
||||||
$this->setData(['user', $userId, 'connectFail', 0]);
|
$this->setData(['user', $userId, 'connectFail', 0], false);
|
||||||
$this->setData(['user', $userId, 'connectTimeout', 0]);
|
$this->setData(['user', $userId, 'connectTimeout', 0], false);
|
||||||
// Expiration
|
|
||||||
|
// 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;
|
$expire = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? strtotime("+1 year") : 0;
|
||||||
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
|
switch ($this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN)) {
|
||||||
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
|
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);
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Connexion par clé
|
||||||
|
setcookie('ZWII_AUTH_KEY', $authKey, $expire, helper::baseUrl(false, false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Accès multiples avec le même compte
|
// 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
|
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
|
||||||
if (
|
if (
|
||||||
$this->getData(['config', 'maintenance'])
|
$this->getData(['config', 'maintenance'])
|
||||||
@ -1157,11 +1367,11 @@ class user extends common
|
|||||||
$logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha';
|
$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
|
// 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'])) {
|
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
|
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
|
||||||
if ($this->getdata(['user', $userId, 'connectFail']) == $this->getData(['config', 'connect', 'attempt'])) {
|
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
|
// Cas 3 le délai de bloquage court
|
||||||
if ($this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time()) {
|
if ($this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time()) {
|
||||||
@ -1174,7 +1384,10 @@ class user extends common
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Sauvegarde la base manuellement
|
||||||
|
$this->saveDB(module: 'user');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Journalisation
|
// Journalisation
|
||||||
$this->saveLog($logStatus);
|
$this->saveLog($logStatus);
|
||||||
|
|
||||||
@ -1197,7 +1410,8 @@ class user extends common
|
|||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
helper::deleteCookie('ZWII_USER_ID');
|
helper::deleteCookie('ZWII_USER_ID');
|
||||||
helper::deleteCookie('ZWII_USER_PASSWORD');
|
//helper::deleteCookie('ZWII_USER_PASSWORD');
|
||||||
|
helper::deleteCookie('ZWII_AUTH_KEY');
|
||||||
|
|
||||||
// Détruit la session
|
// Détruit la session
|
||||||
session_destroy();
|
session_destroy();
|
||||||
@ -1222,13 +1436,29 @@ class user extends common
|
|||||||
// Lien de réinitialisation trop vieux
|
// Lien de réinitialisation trop vieux
|
||||||
or $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time()
|
or $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time()
|
||||||
// Id unique incorrecte
|
// 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
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'redirect' => helper::baseurl(),
|
'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
|
'state' => false
|
||||||
//'access' => false
|
//'access' => false
|
||||||
]);
|
]);
|
||||||
@ -1251,12 +1481,14 @@ class user extends common
|
|||||||
$newPassword = $this->getInput('userResetNewPassword', helper::FILTER_PASSWORD, true);
|
$newPassword = $this->getInput('userResetNewPassword', helper::FILTER_PASSWORD, true);
|
||||||
}
|
}
|
||||||
// Modifie le mot de passe
|
// 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
|
// 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
|
// Réinitialise le blocage
|
||||||
$this->setData(['user', $this->getUrl(2), 'connectFail', 0]);
|
$this->setData(['user', $this->getUrl(2), 'connectFail', 0], false);
|
||||||
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0]);
|
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0], false);
|
||||||
|
// Sauvegarde la base manuellement
|
||||||
|
$this->saveDB('user');
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
$this->addOutput([
|
$this->addOutput([
|
||||||
'notification' => helper::translate('Nouveau mot de passe enregistré'),
|
'notification' => helper::translate('Nouveau mot de passe enregistré'),
|
||||||
@ -1370,7 +1602,7 @@ class user extends common
|
|||||||
"accessCsrf" => null,
|
"accessCsrf" => null,
|
||||||
'tags' => $item['tags']
|
'tags' => $item['tags']
|
||||||
]
|
]
|
||||||
]);
|
], false);
|
||||||
// Icône de notification
|
// Icône de notification
|
||||||
$item['notification'] = $create ? template::ico('check') : template::ico('cancel');
|
$item['notification'] = $create ? template::ico('check') : template::ico('cancel');
|
||||||
// Envoi du mail
|
// Envoi du mail
|
||||||
@ -1411,6 +1643,8 @@ class user extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Sauvegarde la base manuellement
|
||||||
|
$this->saveDB(module: 'user');
|
||||||
if (empty(self::$users)) {
|
if (empty(self::$users)) {
|
||||||
$notification = helper::translate('Rien à importer, erreur de format ou fichier incorrect');
|
$notification = helper::translate('Rien à importer, erreur de format ou fichier incorrect');
|
||||||
$success = false;
|
$success = false;
|
||||||
@ -1452,6 +1686,154 @@ class user extends common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function tag()
|
||||||
|
{
|
||||||
|
// Contenu sélectionné
|
||||||
|
$courseId = $this->getUrl(2);
|
||||||
|
|
||||||
|
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
|
||||||
|
if (
|
||||||
|
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
|
||||||
|
) {
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'access' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inscription des utilisateurs cochés
|
||||||
|
if (
|
||||||
|
isset($_POST['usersTagSubmit'])
|
||||||
|
) {
|
||||||
|
$notification = helper::translate('Modification de %s étiquette(s)');
|
||||||
|
$success = true;
|
||||||
|
$count = 0;
|
||||||
|
$newTags = $this->getInput('usersTagLabel', null, true);
|
||||||
|
foreach ($_POST as $keyPost => $valuePost) {
|
||||||
|
// Exclure les variables post qui ne sont pas des userId et ne traiter que les non inscrits
|
||||||
|
if (
|
||||||
|
$this->getData(['user', $keyPost]) !== null
|
||||||
|
) {
|
||||||
|
$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',
|
||||||
|
'notification' => sprintf($count > 1 ? $notification . 's' : $notification, $count),
|
||||||
|
'state' => $success
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Liste des groupes et des profils
|
||||||
|
$usersGroups = $this->getData(['profil']);
|
||||||
|
|
||||||
|
foreach ($usersGroups as $groupId => $groupValue) {
|
||||||
|
switch ($groupId) {
|
||||||
|
case "-1":
|
||||||
|
case "0":
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
self::$usersGroups['30'] = 'Administrateur';
|
||||||
|
$profils['30'] = 0;
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
case "2":
|
||||||
|
foreach ($groupValue as $profilId => $profilValue) {
|
||||||
|
if ($profilId) {
|
||||||
|
self::$usersGroups[$groupId . $profilId] = sprintf(helper::translate('Groupe %s - Profil %s'), self::$groupPublics[$groupId], $profilValue['name']);
|
||||||
|
$profils[$groupId . $profilId] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste alphabétique
|
||||||
|
self::$alphabet = range('A', 'Z');
|
||||||
|
$alphabet = range('A', 'Z');
|
||||||
|
self::$alphabet = array_combine($alphabet, self::$alphabet);
|
||||||
|
self::$alphabet = array_merge(['all' => 'Tout'], self::$alphabet);
|
||||||
|
|
||||||
|
// Liste des inscrits dans le contenu sélectionné.
|
||||||
|
$users = $this->getData(['user']);
|
||||||
|
if (is_array($users)) {
|
||||||
|
// Tri du tableau par défaut par $userId
|
||||||
|
ksort($users);
|
||||||
|
foreach ($users as $userId => $userValue) {
|
||||||
|
|
||||||
|
// Compte les rôles
|
||||||
|
if (isset($profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])])) {
|
||||||
|
$profils[$this->getData(['user', $userId, 'group']) . $this->getData(['user', $userId, 'profil'])]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtres
|
||||||
|
if (
|
||||||
|
isset($_POST['usersFilterGroup'])
|
||||||
|
|| isset($_POST['usersFilterFirstName'])
|
||||||
|
|| isset($_POST['usersFilterLastName'])
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Groupe et profils
|
||||||
|
$group = (string) $this->getData(['user', $userId, 'group']);
|
||||||
|
$profil = (string) $this->getData(['user', $userId, 'profil']);
|
||||||
|
$firstName = $this->getData(['user', $userId, 'firstname']);
|
||||||
|
$lastName = $this->getData(['user', $userId, 'lastname']);
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterGroup', helper::FILTER_INT) > 0
|
||||||
|
&& $this->getInput('usersFilterGroup', helper::FILTER_STRING_SHORT) !== $group . $profil
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
// Première lettre du prénom
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterFirstName', helper::FILTER_STRING_SHORT) !== 'all'
|
||||||
|
&& $this->getInput('usersFilterFirstName', helper::FILTER_STRING_SHORT) !== strtoupper(substr($firstName, 0, 1))
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
// Première lettre du nom
|
||||||
|
if (
|
||||||
|
$this->getInput('usersFilterLastName', helper::FILTER_STRING_SHORT) !== 'all'
|
||||||
|
&& $this->getInput('usersFilterLastName', helper::FILTER_STRING_SHORT) !== strtoupper(substr($lastName, 0, 1))
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construction du tableau
|
||||||
|
self::$users[] = [
|
||||||
|
template::checkbox($userId, true, '', ['class' => 'checkboxSelect']),
|
||||||
|
$userId,
|
||||||
|
$this->getData(['user', $userId, 'firstname']),
|
||||||
|
$this->getData(['user', $userId, 'lastname']),
|
||||||
|
$this->getData(['user', $userId, 'tags']),
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajoute les effectifs aux profils du sélecteur
|
||||||
|
foreach (self::$usersGroups as $groupId => $groupValue) {
|
||||||
|
if ($groupId === 'all') {
|
||||||
|
self::$usersGroups['all'] = self::$usersGroups['all'] . ' (' . array_sum($profils) . ')';
|
||||||
|
} else {
|
||||||
|
self::$usersGroups[$groupId] = self::$usersGroups[$groupId] . ' (' . $profils[$groupId] . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valeurs en sortie
|
||||||
|
$this->addOutput([
|
||||||
|
'view' => 'tag',
|
||||||
|
'title' => 'Étiquettes',
|
||||||
|
'vendor' => [
|
||||||
|
'datatables'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liste les dossier contenus dans RFM
|
* Liste les dossier contenus dans RFM
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,7 @@ $(document).ready((function () {
|
|||||||
},
|
},
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
|
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
target: 5,
|
target: 5,
|
||||||
|
@ -6,27 +6,35 @@
|
|||||||
'value' => template::ico('home')
|
'value' => template::ico('home')
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2 offset2">
|
||||||
<?php /**echo template::button('userHelp', [
|
|
||||||
'href' => 'https://doc.zwiicms.fr/gestion-des-utilisateurs',
|
|
||||||
'target' => '_blank',
|
|
||||||
'value' => template::ico('help'),
|
|
||||||
'class' => 'buttonHelp',
|
|
||||||
'help' => 'Consulter l\'aide en ligne'
|
|
||||||
]);*/?>
|
|
||||||
</div>
|
|
||||||
<div class="col1 offset7">
|
|
||||||
<?php echo template::button('userImport', [
|
<?php echo template::button('userImport', [
|
||||||
'href' => helper::baseUrl() . 'user/import',
|
'href' => helper::baseUrl() . 'user/import',
|
||||||
'value' => template::ico('upload'),
|
'ico' => 'users',
|
||||||
'help' => 'Importer des utilisateurs en masse'
|
'value' => 'Importer en masse'
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col2">
|
||||||
|
<?php echo template::button('userDeleteAll', [
|
||||||
|
'class' => 'userDeleteAll buttonRed',
|
||||||
|
'href' => helper::baseUrl() . 'user/usersDelete/' . $this->getUrl(2),
|
||||||
|
'ico' => 'users',
|
||||||
|
'value' => 'Désinscrire en masse',
|
||||||
|
]) ?>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<?php echo template::button('userTag', [
|
||||||
|
'href' => helper::baseUrl() . 'user/tag',
|
||||||
|
'ico' => 'tags',
|
||||||
|
'value' => 'Étiquettes',
|
||||||
|
'help' => 'Filtrer les utilisateurs avec des tags'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
<?php echo template::button('userGroup', [
|
<?php echo template::button('userGroup', [
|
||||||
'href' => helper::baseUrl() . 'user/profil',
|
'href' => helper::baseUrl() . 'user/profil',
|
||||||
'value' => template::ico('lock'),
|
'ico' => 'lock',
|
||||||
'help' => 'Profils'
|
'value' => 'Profils',
|
||||||
|
'help' => 'Permissions par profils'
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col1">
|
<div class="col1">
|
||||||
@ -60,4 +68,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php echo template::formClose(); ?>
|
<?php echo template::formClose(); ?>
|
||||||
<?php echo template::table([3, 2, 2, 2, 2, 1, 1], $module::$users, [ 'Nom', 'Groupe', 'Profil', 'Étiquettes', 'Date dernière vue', '', ''], ['id' => 'dataTables']); ?>
|
<?php echo template::table([3, 2, 2, 2, 2, 1, 1], $module::$users, ['Nom', 'Groupe', 'Profil', 'Étiquettes', 'Date dernière vue', '', ''], ['id' => 'dataTables']); ?>
|
@ -8,4 +8,32 @@
|
|||||||
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
|
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
|
||||||
* @link http://zwiicms.fr/
|
* @link http://zwiicms.fr/
|
||||||
*/
|
*/
|
||||||
$(document).ready((function(){$(".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")
|
||||||
|
}))
|
||||||
|
}));
|
@ -180,11 +180,15 @@
|
|||||||
<div class="col3">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilAddCourseRestore', true, 'Restaurer un espace'); ?>
|
<?php echo template::checkbox('profilAddCourseRestore', true, 'Restaurer un espace'); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilAddCourseUsers', true, 'Gérer les participants'); ?>
|
<?php echo template::checkbox('profilAddCourseUsers', true, 'Gérer les participants'); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::checkbox('profilAddCourseExport', true, 'Exporter un espace en html'); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="courseContainer">
|
<div id="courseContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -192,7 +196,7 @@
|
|||||||
<?php echo template::checkbox('profilAddCourseUserHistory', true, 'Voir historique d\'un participant'); ?>
|
<?php echo template::checkbox('profilAddCourseUserHistory', true, 'Voir historique d\'un participant'); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col3">
|
<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>
|
||||||
<div class="col3">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilAddCourseUserDelete', true, 'Désinscrire un participant'); ?>
|
<?php echo template::checkbox('profilAddCourseUserDelete', true, 'Désinscrire un participant'); ?>
|
||||||
@ -205,6 +209,9 @@
|
|||||||
<div class="col3">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilAddCourseUsersDelete', true, 'Désinscrire en masse'); ?>
|
<?php echo template::checkbox('profilAddCourseUsersDelete', true, 'Désinscrire en masse'); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::checkbox('profilAddCourseReset', true, 'Réinitialiser un espace'); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,6 +54,19 @@ $(document).ready(function () {
|
|||||||
$(".containerModule").slideDown();
|
$(".containerModule").slideDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($('#profilEditCourseUsers').is(':checked')) {
|
||||||
|
// Activer les autres checkboxes
|
||||||
|
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
// Désactiver les autres checkboxes
|
||||||
|
$('#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// EVENEMENTS
|
||||||
|
|
||||||
// À chaque inversion de l'état du checkbox avec l'id "profilEditFileManager", désactive ou active tous les éléments de la classe "filemanager" en fonction de l'état
|
// À chaque inversion de l'état du checkbox avec l'id "profilEditFileManager", désactive ou active tous les éléments de la classe "filemanager" en fonction de l'état
|
||||||
$("#profilEditFileManager").change(function () {
|
$("#profilEditFileManager").change(function () {
|
||||||
if (!$(this).is(':checked')) {
|
if (!$(this).is(':checked')) {
|
||||||
@ -118,4 +131,20 @@ $(document).ready(function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Gérer l’évènement de modification de la checkbox #profilEditCourse
|
||||||
|
$('#profilEditCourseUsers').change(function () {
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
// Activer les autres checkboxes
|
||||||
|
$('#profilEditCourseUserHistory, #profilEditCourseuserReportExport, #profilEditCourseUserDelete, #profilEditCourseUsersAdd, #profilEditCourseUsersDelete, #profilEditCourseReset').prop('disabled', false);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Désactiver les autres checkboxes
|
||||||
|
$('#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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -97,9 +97,9 @@
|
|||||||
'label' => 'Dossier depuis un espace',
|
'label' => 'Dossier depuis un espace',
|
||||||
'class' => 'filemanager',
|
'class' => 'filemanager',
|
||||||
/*
|
/*
|
||||||
* 'none' interdit l'accès au gestionnaire de fichier
|
* 'none' interdit l'accès au gestionnaire de fichier
|
||||||
* Ce n'est pas un chemin donc on n'ajoute pas le .
|
* Ce n'est pas un chemin donc on n'ajoute pas le .
|
||||||
*/
|
*/
|
||||||
'selected' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'folder', 'coursePath'])
|
'selected' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'folder', 'coursePath'])
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
@ -272,11 +272,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col6">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilEditCourseUsers', true, 'Gérer les participants', [
|
<?php echo template::checkbox('profilEditCourseUsers', true, 'Gérer les participants', [
|
||||||
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'users']),
|
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'users']),
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::checkbox('profilEditCourseExport', true, 'Exporter un espace en html', [
|
||||||
|
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'export']),
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="courseContainer">
|
<div id="courseContainer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -286,8 +291,8 @@
|
|||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col3">
|
<div class="col3">
|
||||||
<?php echo template::checkbox('profilEditCourseUserHistoryExport', true, 'Exporter historique d\'un participant', [
|
<?php echo template::checkbox('profilEditCourseuserReportExport', true, 'Exporter historique d\'un participant', [
|
||||||
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'userHistoryExport']),
|
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'userReportExport']),
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col3">
|
<div class="col3">
|
||||||
@ -307,6 +312,11 @@
|
|||||||
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'usersDelete']),
|
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'usersDelete']),
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::checkbox('profilEditCourseReset', true, 'Réinitialiser un espace', [
|
||||||
|
'checked' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'course', 'reset']),
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
18
core/module/user/view/tag/tag.css
Normal file
18
core/module/user/view/tag/tag.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of Zwii.
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
* @author Rémi Jean <remi.jean@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||||
|
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
|
||||||
|
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
|
||||||
|
* @link http://zwiicms.fr/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** NE PAS EFFACER
|
||||||
|
* admin.css
|
||||||
|
*/
|
101
core/module/user/view/tag/tag.js.php
Normal file
101
core/module/user/view/tag/tag.js.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* 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 () {
|
||||||
|
|
||||||
|
$('tr').click(function () {
|
||||||
|
// Cochez ou décochez la case à cocher dans cette ligne
|
||||||
|
$(this).find('input[type="checkbox"]').prop('checked', function (i, val) {
|
||||||
|
return !val; // Inverse l'état actuel de la case à cocher
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#usersTagSelectAll').on('click', function () {
|
||||||
|
$('.checkboxSelect').prop('checked', true);
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
$('#usersTagSelectNone').on('click', function () {
|
||||||
|
$('.checkboxSelect').prop('checked', false);
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#usersFilterGroup, #usersFilterFirstName, #usersFilterLastName").change(function () {
|
||||||
|
saveCheckboxState();
|
||||||
|
$("#usersTagForm").submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
var table = $('#dataTables').DataTable({
|
||||||
|
language: {
|
||||||
|
url: "core/vendor/datatables/french.json"
|
||||||
|
},
|
||||||
|
locale: 'fr',
|
||||||
|
"lengthMenu": [[10, 25, 50, 100, 299, -1], [10, 25, 50, 100, 200, "Tout"]],
|
||||||
|
"columnDefs": [
|
||||||
|
{
|
||||||
|
target: 0,
|
||||||
|
orderable: false,
|
||||||
|
searchable: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle checkbox change event
|
||||||
|
$('.checkboxSelect').on('change', function () {
|
||||||
|
// Save checkbox state to cookies or local storage
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle checkbox state on DataTables draw event
|
||||||
|
table.on('draw', function () {
|
||||||
|
// Restore checkbox state from cookies or local storage
|
||||||
|
restoreCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Empty local storage after submit
|
||||||
|
$("#usersTagSubmit").on("click", function () {
|
||||||
|
localStorage.setItem('checkboxState', JSON.stringify({}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Restore checkbox state on page load
|
||||||
|
restoreCheckboxState();
|
||||||
|
|
||||||
|
function saveCheckboxState() {
|
||||||
|
|
||||||
|
// Récupérer d'abord les données existantes dans le localStorage
|
||||||
|
var existingData = JSON.parse(localStorage.getItem('checkboxState')) || {};
|
||||||
|
|
||||||
|
// Ajouter ou mettre à jour les données actuelles
|
||||||
|
$('.checkboxSelect').each(function () {
|
||||||
|
var checkboxId = $(this).attr('id');
|
||||||
|
var checked = $(this).prop('checked');
|
||||||
|
existingData[checkboxId] = checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sauvegarder les données mises à jour dans le localStorage
|
||||||
|
localStorage.setItem('checkboxState', JSON.stringify(existingData));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to restore checkbox state
|
||||||
|
function restoreCheckboxState() {
|
||||||
|
var checkboxState = JSON.parse(localStorage.getItem('checkboxState')) || {};
|
||||||
|
// console.log(checkboxState);
|
||||||
|
for (var checkboxId in checkboxState) {
|
||||||
|
if (checkboxState.hasOwnProperty(checkboxId)) {
|
||||||
|
var checked = checkboxState[checkboxId];
|
||||||
|
// Update checkbox state based on stored information
|
||||||
|
$('#' + checkboxId).prop('checked', checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
65
core/module/user/view/tag/tag.php
Normal file
65
core/module/user/view/tag/tag.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php echo template::formOpen('usersTagForm'); ?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col1">
|
||||||
|
<?php echo template::button('userDeleteBack', [
|
||||||
|
'class' => 'buttonGrey',
|
||||||
|
'href' => helper::baseUrl() . 'user/' . $this->getUrl(2),
|
||||||
|
'value' => template::ico('left')
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col12">
|
||||||
|
<div class="block">
|
||||||
|
<h4>Étiquette de remplacement</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col8">
|
||||||
|
<?php echo template::text('usersTagLabel', [
|
||||||
|
'placeholder' => 'Les étiquettes saisis remplaceront celles existantes. Les étiquettes sont séparées par des espaces'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col2 offset2 verticalAlignBottom">
|
||||||
|
<?php echo template::submit('usersTagSubmit'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="Bfrtip">
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterGroup', $module::$usersGroups, [
|
||||||
|
'label' => 'Groupes / Profils',
|
||||||
|
'selected' => isset($_POST['usersFilterGroup']) ? $_POST['usersFilterGroup'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterFirstName', $module::$alphabet, [
|
||||||
|
'label' => 'Prénom commence par',
|
||||||
|
'selected' => isset($_POST['usersFilterFirstName']) ? $_POST['usersFilterFirstName'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterLastName', $module::$alphabet, [
|
||||||
|
'label' => 'Nom commence par',
|
||||||
|
'selected' => isset($_POST['usersFilterLastName']) ? $_POST['usersFilterLastName'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 offset1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('usersTagSelectAll', [
|
||||||
|
'value' => template::ico('square-check'),
|
||||||
|
'help' => 'Tout sélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('usersTagSelectNone', [
|
||||||
|
'value' => template::ico('square-check-empty'),
|
||||||
|
'help' => 'Tout désélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($module::$users): ?>
|
||||||
|
<?php echo template::table([1, 2, 3, 3, 3], $module::$users, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php echo template::speech('Aucun inscrit'); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php echo template::formClose(); ?>
|
26
core/module/user/view/usersDelete/usersDelete.css
Normal file
26
core/module/user/view/usersDelete/usersDelete.css
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of Zwii.
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
* @author Rémi Jean <remi.jean@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||||
|
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||||
|
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
|
||||||
|
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
|
||||||
|
* @link http://zwiicms.fr/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** NE PAS EFFACER
|
||||||
|
* admin.css
|
||||||
|
*/
|
||||||
|
|
||||||
|
#usersDeleteSubmit {
|
||||||
|
background-color: rgba(217, 95, 78, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
101
core/module/user/view/usersDelete/usersDelete.js.php
Normal file
101
core/module/user/view/usersDelete/usersDelete.js.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* 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 () {
|
||||||
|
|
||||||
|
$('tr').click(function () {
|
||||||
|
// Cochez ou décochez la case à cocher dans cette ligne
|
||||||
|
$(this).find('input[type="checkbox"]').prop('checked', function (i, val) {
|
||||||
|
return !val; // Inverse l'état actuel de la case à cocher
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#usersDeleteSelectAll').on('click', function () {
|
||||||
|
$('.checkboxSelect').prop('checked', true);
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
$('#usersDeleteSelectNone').on('click', function () {
|
||||||
|
$('.checkboxSelect').prop('checked', false);
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#usersFilterGroup, #usersFilterFirstName, #usersFilterLastName").change(function () {
|
||||||
|
saveCheckboxState();
|
||||||
|
$("#usersDeleteForm").submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
var table = $('#dataTables').DataTable({
|
||||||
|
language: {
|
||||||
|
url: "core/vendor/datatables/french.json"
|
||||||
|
},
|
||||||
|
locale: 'fr',
|
||||||
|
"lengthMenu": [[10, 25, 50, 100, 299, -1], [10, 25, 50, 100, 200, "Tout"]],
|
||||||
|
"columnDefs": [
|
||||||
|
{
|
||||||
|
target: 0,
|
||||||
|
orderable: false,
|
||||||
|
searchable: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle checkbox change event
|
||||||
|
$('.checkboxSelect').on('change', function () {
|
||||||
|
// Save checkbox state to cookies or local storage
|
||||||
|
saveCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle checkbox state on DataTables draw event
|
||||||
|
table.on('draw', function () {
|
||||||
|
// Restore checkbox state from cookies or local storage
|
||||||
|
restoreCheckboxState();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Empty local storage after submit
|
||||||
|
$("#usersDeleteSubmit").on("click", function () {
|
||||||
|
localStorage.setItem('checkboxState', JSON.stringify({}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Restore checkbox state on page load
|
||||||
|
restoreCheckboxState();
|
||||||
|
|
||||||
|
function saveCheckboxState() {
|
||||||
|
|
||||||
|
// Récupérer d'abord les données existantes dans le localStorage
|
||||||
|
var existingData = JSON.parse(localStorage.getItem('checkboxState')) || {};
|
||||||
|
|
||||||
|
// Ajouter ou mettre à jour les données actuelles
|
||||||
|
$('.checkboxSelect').each(function () {
|
||||||
|
var checkboxId = $(this).attr('id');
|
||||||
|
var checked = $(this).prop('checked');
|
||||||
|
existingData[checkboxId] = checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sauvegarder les données mises à jour dans le localStorage
|
||||||
|
localStorage.setItem('checkboxState', JSON.stringify(existingData));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to restore checkbox state
|
||||||
|
function restoreCheckboxState() {
|
||||||
|
var checkboxState = JSON.parse(localStorage.getItem('checkboxState')) || {};
|
||||||
|
// console.log(checkboxState);
|
||||||
|
for (var checkboxId in checkboxState) {
|
||||||
|
if (checkboxState.hasOwnProperty(checkboxId)) {
|
||||||
|
var checked = checkboxState[checkboxId];
|
||||||
|
// Update checkbox state based on stored information
|
||||||
|
$('#' + checkboxId).prop('checked', checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
55
core/module/user/view/usersDelete/usersDelete.php
Normal file
55
core/module/user/view/usersDelete/usersDelete.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php echo template::formOpen('usersDeleteForm'); ?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col1">
|
||||||
|
<?php echo template::button('userDeleteBack', [
|
||||||
|
'class' => 'buttonGrey',
|
||||||
|
'href' => helper::baseUrl() . 'user/' . $this->getUrl(2),
|
||||||
|
'value' => template::ico('left')
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 offset10">
|
||||||
|
<?php echo template::submit('usersDeleteSubmit', [
|
||||||
|
'class' => 'buttonRed',
|
||||||
|
'ico' => '',
|
||||||
|
'value' => template::ico('minus'),
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="Bfrtip">
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterGroup', $module::$usersGroups, [
|
||||||
|
'label' => 'Groupes / Profils',
|
||||||
|
'selected' => isset($_POST['usersFilterGroup']) ? $_POST['usersFilterGroup'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterFirstName', $module::$alphabet, [
|
||||||
|
'label' => 'Prénom commence par',
|
||||||
|
'selected' => isset($_POST['usersFilterFirstName']) ? $_POST['usersFilterFirstName'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<?php echo template::select('usersFilterLastName', $module::$alphabet, [
|
||||||
|
'label' => 'Nom commence par',
|
||||||
|
'selected' => isset($_POST['usersFilterLastName']) ? $_POST['usersFilterLastName'] : 'all',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 offset1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('usersDeleteSelectAll', [
|
||||||
|
'value' => template::ico('square-check'),
|
||||||
|
'help' => 'Tout sélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col1 verticalAlignBottom">
|
||||||
|
<?php echo template::button('usersDeleteSelectNone', [
|
||||||
|
'value' => template::ico('square-check-empty'),
|
||||||
|
'help' => 'Tout désélectionner'
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($module::$users): ?>
|
||||||
|
<?php echo template::table([1, 2, 3, 3, 3], $module::$users, ['', 'Id', 'Prénom', 'Nom', 'Étiquettes'], ['id' => 'dataTables']); ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php echo template::speech('Aucun inscrit'); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php echo template::formClose(); ?>
|
13
core/vendor/datatables/datatables.custom.css
vendored
Normal file
13
core/vendor/datatables/datatables.custom.css
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.dataTables_length {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_length label {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_length select {
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 80px;
|
||||||
|
}
|
2
core/vendor/datatables/french.json
vendored
2
core/vendor/datatables/french.json
vendored
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"processing": "Traitement en cours...",
|
"processing": "Traitement en cours...",
|
||||||
"search": "Rechercher :",
|
"search": "Rechercher :",
|
||||||
"lengthMenu": "Éléments par page _MENU_",
|
"lengthMenu": "Éléments par page : _MENU_",
|
||||||
"info": "Affichage de l'élement _START_ à _END_ sur _TOTAL_ éléments",
|
"info": "Affichage de l'élement _START_ à _END_ sur _TOTAL_ éléments",
|
||||||
"infoEmpty": "Affichage de l'élement 0 à 0 sur 0 éléments",
|
"infoEmpty": "Affichage de l'élement 0 à 0 sur 0 éléments",
|
||||||
"infoFiltered": "(filtré de _MAX_ éléments au total)",
|
"infoFiltered": "(filtré de _MAX_ éléments au total)",
|
||||||
|
5
core/vendor/datatables/inc.json
vendored
5
core/vendor/datatables/inc.json
vendored
@ -1,6 +1,7 @@
|
|||||||
[
|
[
|
||||||
"datatables.min.js",
|
"datatables.min.js",
|
||||||
"moment.min.js",
|
"moment.min.js",
|
||||||
"datetime.min.js",
|
"datetime.min.js",
|
||||||
"datatables.min.css"
|
"datatables.min.css",
|
||||||
|
"datatables.custom.css"
|
||||||
]
|
]
|
5
core/vendor/filemanager/UploadHandler.php
vendored
5
core/vendor/filemanager/UploadHandler.php
vendored
@ -1506,8 +1506,9 @@ class UploadHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$newWidth = 640;
|
||||||
$thumbResult = create_img($targetFile, $targetFileThumb, 122, 91);
|
$newHeight = 480;
|
||||||
|
$thumbResult = create_img($targetFile, $targetFileThumb, $newWidth, $newHeight);
|
||||||
|
|
||||||
if ( $thumbResult!==true)
|
if ( $thumbResult!==true)
|
||||||
{
|
{
|
||||||
|
4
core/vendor/filemanager/config/config.php
vendored
4
core/vendor/filemanager/config/config.php
vendored
@ -19,7 +19,7 @@ setlocale(LC_CTYPE, $lang);
|
|||||||
|
|
||||||
/* Lecture du groupe de l'utilisateur connecté pour attribuer les droits et les dossiers */
|
/* Lecture du groupe de l'utilisateur connecté pour attribuer les droits et les dossiers */
|
||||||
$userId = $_COOKIE['ZWII_USER_ID'];
|
$userId = $_COOKIE['ZWII_USER_ID'];
|
||||||
$courseId = $_COOKIE['ZWII_SITE_CONTENT'];
|
$courseId = $_GET['lang'];
|
||||||
$u = json_decode(file_get_contents('../../../site/data/user.json'), true);
|
$u = json_decode(file_get_contents('../../../site/data/user.json'), true);
|
||||||
$g = json_decode(file_get_contents('../../../site/data/profil.json'), true);
|
$g = json_decode(file_get_contents('../../../site/data/profil.json'), true);
|
||||||
|
|
||||||
@ -609,7 +609,7 @@ $config = array(
|
|||||||
// path_from_filemanager/test/test1/
|
// path_from_filemanager/test/test1/
|
||||||
// PS if there isn't write permission in your destination folder you must set it
|
// 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
|
//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_from_filemanager' => array('../../../site/file/thumb/'),
|
||||||
//fixed path of the image folder from the current position on upload folder
|
//fixed path of the image folder from the current position on upload folder
|
||||||
|
126
core/vendor/tinymce/init.js
vendored
126
core/vendor/tinymce/init.js
vendored
@ -10,23 +10,43 @@
|
|||||||
if (typeof (privateKey) == 'undefined') {
|
if (typeof (privateKey) == 'undefined') {
|
||||||
var privateKey = null;
|
var privateKey = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
tinymce.init({
|
tinymce.init({
|
||||||
// Classe où appliquer l'éditeur
|
// Classe où appliquer l'éditeur
|
||||||
selector: ".editorWysiwyg",
|
selector: ".editorWysiwyg",
|
||||||
// Aperçu dans le pied de page
|
// Aperçu dans le pied de page
|
||||||
setup: function (ed) {
|
setup: function (editor) {
|
||||||
ed.on('change', function (e) {
|
// Événement 'change'
|
||||||
if (ed.id === 'themeFooterText') {
|
editor.on('change', function (e) {
|
||||||
|
if (editor.id === 'themeFooterText') {
|
||||||
$("#footerText").html(tinyMCE.get('themeFooterText').getContent());
|
$("#footerText").html(tinyMCE.get('themeFooterText').getContent());
|
||||||
}
|
}
|
||||||
if (ed.id === 'themeHeaderText') {
|
if (editor.id === 'themeHeaderText') {
|
||||||
$("#featureContent").html(tinyMCE.get('themeHeaderText').getContent());
|
$("#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
|
// Langue
|
||||||
language: getCookie('ZWII_UI') === null ? "fr_FR" : getCookie('ZWII_UI'),
|
language:"fr_FR",
|
||||||
// Plugins
|
// 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",
|
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
|
// Contenu du menu
|
||||||
@ -35,7 +55,6 @@ tinymce.init({
|
|||||||
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
|
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
|
||||||
view: { title: 'View', items: 'code | visualaid visualblocks | fullscreen' },
|
view: { title: 'View', items: 'code | visualaid visualblocks | fullscreen' },
|
||||||
insert: { title: 'Insert', items: 'image link media pageembed template inserttable | charmap emoticons hr | nonbreaking anchor' },
|
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: '' },
|
tools: { title: 'Tools', items: '' },
|
||||||
table: { title: 'Table', items: 'inserttable | cell row column | tableprops deletetable' },
|
table: { title: 'Table', items: 'inserttable | cell row column | tableprops deletetable' },
|
||||||
help: { title: 'Help', items: 'help' }
|
help: { title: 'Help', items: 'help' }
|
||||||
@ -56,7 +75,6 @@ tinymce.init({
|
|||||||
saveCursorPosition: false, // Insert caret marker
|
saveCursorPosition: false, // Insert caret marker
|
||||||
config: { // CodeMirror config object
|
config: { // CodeMirror config object
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
/*mode: 'application/x-httpd-php',*/
|
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
indentUnit: 4,
|
indentUnit: 4,
|
||||||
mode: "htmlmixed"
|
mode: "htmlmixed"
|
||||||
@ -71,12 +89,8 @@ tinymce.init({
|
|||||||
'addon/search/searchcursor.js',
|
'addon/search/searchcursor.js',
|
||||||
'addon/search/search.js',
|
'addon/search/search.js',
|
||||||
],
|
],
|
||||||
/*
|
width: 800,
|
||||||
cssFiles: [
|
height: 500
|
||||||
'theme/cobalt.css',
|
|
||||||
],*/
|
|
||||||
width: 800, // Default value is 800
|
|
||||||
height: 500 // Default value is 550
|
|
||||||
},
|
},
|
||||||
// Cibles de la target
|
// Cibles de la target
|
||||||
target_list: [
|
target_list: [
|
||||||
@ -89,7 +103,7 @@ tinymce.init({
|
|||||||
{ title: 'Une popup (Lity)', value: 'data-lity' },
|
{ title: 'Une popup (Lity)', value: 'data-lity' },
|
||||||
{ title: 'Une galerie d\'images (SimpleLightbox)', value: 'gallery' }
|
{ title: 'Une galerie d\'images (SimpleLightbox)', value: 'gallery' }
|
||||||
],
|
],
|
||||||
// Titre des image
|
// Titre des images
|
||||||
image_title: true,
|
image_title: true,
|
||||||
// Pages internes
|
// Pages internes
|
||||||
link_list: baseUrl + "core/vendor/tinymce/links.php",
|
link_list: baseUrl + "core/vendor/tinymce/links.php",
|
||||||
@ -99,7 +113,7 @@ tinymce.init({
|
|||||||
content_css: [
|
content_css: [
|
||||||
baseUrl + "core/layout/common.css",
|
baseUrl + "core/layout/common.css",
|
||||||
baseUrl + "core/vendor/tinymce/content.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"
|
baseUrl + "site/data/custom.css"
|
||||||
],
|
],
|
||||||
// Classe à ajouter à la balise body dans l'iframe
|
// Classe à ajouter à la balise body dans l'iframe
|
||||||
@ -226,26 +240,26 @@ tinymce.init({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
textpattern_patterns: [
|
textpattern_patterns: [
|
||||||
{start: '*', end: '*', format: 'italic'},
|
{ start: '*', end: '*', format: 'italic' },
|
||||||
{start: '**', end: '**', format: 'bold'},
|
{ start: '**', end: '**', format: 'bold' },
|
||||||
{start: '#', format: 'h1'},
|
{ start: '#', format: 'h1' },
|
||||||
{start: '##', format: 'h2'},
|
{ start: '##', format: 'h2' },
|
||||||
{start: '###', format: 'h3'},
|
{ start: '###', format: 'h3' },
|
||||||
{start: '####', format: 'h4'},
|
{ start: '####', format: 'h4' },
|
||||||
{start: '#####', format: 'h5'},
|
{ start: '#####', format: 'h5' },
|
||||||
{start: '######', format: 'h6'},
|
{ start: '######', format: 'h6' },
|
||||||
{start: '1. ', cmd: 'InsertOrderedList'},
|
{ start: '1. ', cmd: 'InsertOrderedList' },
|
||||||
{start: '* ', cmd: 'InsertUnorderedList'},
|
{ start: '* ', cmd: 'InsertUnorderedList' },
|
||||||
{start: '- ', cmd: 'InsertUnorderedList'},
|
{ start: '- ', cmd: 'InsertUnorderedList' },
|
||||||
{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: '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: '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: '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
|
// Langue
|
||||||
language: getCookie('ZWII_UI') === null ? "fr_FR" : getCookie('ZWII_UI'),
|
language: "fr_FR",
|
||||||
// Plugins
|
// Plugins
|
||||||
plugins: "advlist anchor autolink autoresize autosave colorpicker contextmenu hr lists paste searchreplace tabfocus template textcolor textpattern",
|
plugins: "advlist anchor autolink autoresize autosave colorpicker contextmenu hr lists paste searchreplace tabfocus template textcolor textpattern",
|
||||||
// Contenu de la barre d'outils
|
// Contenu de la barre d'outils
|
||||||
@ -344,26 +358,26 @@ tinymce.init({
|
|||||||
document_base_url: baseUrl,
|
document_base_url: baseUrl,
|
||||||
max_height: 200,
|
max_height: 200,
|
||||||
textpattern_patterns: [
|
textpattern_patterns: [
|
||||||
{start: '*', end: '*', format: 'italic'},
|
{ start: '*', end: '*', format: 'italic' },
|
||||||
{start: '**', end: '**', format: 'bold'},
|
{ start: '**', end: '**', format: 'bold' },
|
||||||
{start: '#', format: 'h1'},
|
{ start: '#', format: 'h1' },
|
||||||
{start: '##', format: 'h2'},
|
{ start: '##', format: 'h2' },
|
||||||
{start: '###', format: 'h3'},
|
{ start: '###', format: 'h3' },
|
||||||
{start: '####', format: 'h4'},
|
{ start: '####', format: 'h4' },
|
||||||
{start: '#####', format: 'h5'},
|
{ start: '#####', format: 'h5' },
|
||||||
{start: '######', format: 'h6'},
|
{ start: '######', format: 'h6' },
|
||||||
{start: '1. ', cmd: 'InsertOrderedList'},
|
{ start: '1. ', cmd: 'InsertOrderedList' },
|
||||||
{start: '* ', cmd: 'InsertUnorderedList'},
|
{ start: '* ', cmd: 'InsertUnorderedList' },
|
||||||
{start: '- ', cmd: 'InsertUnorderedList'},
|
{ start: '- ', cmd: 'InsertUnorderedList' },
|
||||||
{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: '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: '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: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' }}
|
{ start: 'i) ', cmd: 'InsertOrderedList', value: { 'list-style-type': 'lower-roman' } }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
3
core/vendor/zwiico/css/zwiico-codes.css
vendored
3
core/vendor/zwiico/css/zwiico-codes.css
vendored
@ -1,6 +1,7 @@
|
|||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
|
||||||
.zwiico-plus-circled:before { content: '\2191'; } /* '↑' */
|
.zwiico-plus-circled:before { content: '\2191'; } /* '↑' */
|
||||||
|
.zwiico-square-check:before { content: '\e800'; } /* '' */
|
||||||
.zwiico-plus:before { content: '\e801'; } /* '' */
|
.zwiico-plus:before { content: '\e801'; } /* '' */
|
||||||
.zwiico-cancel:before { content: '\e802'; } /* '' */
|
.zwiico-cancel:before { content: '\e802'; } /* '' */
|
||||||
.zwiico-help:before { content: '\e803'; } /* '' */
|
.zwiico-help:before { content: '\e803'; } /* '' */
|
||||||
@ -48,7 +49,9 @@
|
|||||||
.zwiico-right-dir:before { content: '\e82d'; } /* '' */
|
.zwiico-right-dir:before { content: '\e82d'; } /* '' */
|
||||||
.zwiico-chart-line:before { content: '\e82e'; } /* '' */
|
.zwiico-chart-line:before { content: '\e82e'; } /* '' */
|
||||||
.zwiico-book:before { content: '\e82f'; } /* '' */
|
.zwiico-book:before { content: '\e82f'; } /* '' */
|
||||||
|
.zwiico-square-check-empty:before { content: '\e830'; } /* '' */
|
||||||
.zwiico-spin:before { content: '\e831'; } /* '' */
|
.zwiico-spin:before { content: '\e831'; } /* '' */
|
||||||
|
.zwiico-tags:before { content: '\e832'; } /* '' */
|
||||||
.zwiico-twitter:before { content: '\f099'; } /* '' */
|
.zwiico-twitter:before { content: '\f099'; } /* '' */
|
||||||
.zwiico-facebook:before { content: '\f09a'; } /* '' */
|
.zwiico-facebook:before { content: '\f09a'; } /* '' */
|
||||||
.zwiico-docs:before { content: '\f0c5'; } /* '' */
|
.zwiico-docs:before { content: '\f0c5'; } /* '' */
|
||||||
|
15
core/vendor/zwiico/css/zwiico-embedded.css
vendored
15
core/vendor/zwiico/css/zwiico-embedded.css
vendored
File diff suppressed because one or more lines are too long
3
core/vendor/zwiico/css/zwiico-ie7-codes.css
vendored
3
core/vendor/zwiico/css/zwiico-ie7-codes.css
vendored
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
.zwiico-plus-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '↑ '); }
|
.zwiico-plus-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '↑ '); }
|
||||||
|
.zwiico-square-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
@ -47,7 +48,9 @@
|
|||||||
.zwiico-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.zwiico-square-check-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-spin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-spin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.zwiico-tags { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-docs { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-docs { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
3
core/vendor/zwiico/css/zwiico-ie7.css
vendored
3
core/vendor/zwiico/css/zwiico-ie7.css
vendored
@ -11,6 +11,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.zwiico-plus-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '↑ '); }
|
.zwiico-plus-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '↑ '); }
|
||||||
|
.zwiico-square-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
@ -58,7 +59,9 @@
|
|||||||
.zwiico-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.zwiico-square-check-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-spin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-spin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.zwiico-tags { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.zwiico-docs { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.zwiico-docs { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
17
core/vendor/zwiico/css/zwiico.css
vendored
17
core/vendor/zwiico/css/zwiico.css
vendored
@ -1,12 +1,12 @@
|
|||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'zwiico';
|
font-family: 'zwiico';
|
||||||
src: url('../font/zwiico.eot?8645815');
|
src: url('../font/zwiico.eot?24931130');
|
||||||
src: url('../font/zwiico.eot?8645815#iefix') format('embedded-opentype'),
|
src: url('../font/zwiico.eot?24931130#iefix') format('embedded-opentype'),
|
||||||
url('../font/zwiico.woff2?8645815') format('woff2'),
|
url('../font/zwiico.woff2?24931130') format('woff2'),
|
||||||
url('../font/zwiico.woff?8645815') format('woff'),
|
url('../font/zwiico.woff?24931130') format('woff'),
|
||||||
url('../font/zwiico.ttf?8645815') format('truetype'),
|
url('../font/zwiico.ttf?24931130') format('truetype'),
|
||||||
url('../font/zwiico.svg?8645815#zwiico') format('svg');
|
url('../font/zwiico.svg?24931130#zwiico') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@
|
|||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'zwiico';
|
font-family: 'zwiico';
|
||||||
src: url('../font/zwiico.svg?8645815#zwiico') format('svg');
|
src: url('../font/zwiico.svg?24931130#zwiico') format('svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -56,6 +56,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.zwiico-plus-circled:before { content: '\2191'; } /* '↑' */
|
.zwiico-plus-circled:before { content: '\2191'; } /* '↑' */
|
||||||
|
.zwiico-square-check:before { content: '\e800'; } /* '' */
|
||||||
.zwiico-plus:before { content: '\e801'; } /* '' */
|
.zwiico-plus:before { content: '\e801'; } /* '' */
|
||||||
.zwiico-cancel:before { content: '\e802'; } /* '' */
|
.zwiico-cancel:before { content: '\e802'; } /* '' */
|
||||||
.zwiico-help:before { content: '\e803'; } /* '' */
|
.zwiico-help:before { content: '\e803'; } /* '' */
|
||||||
@ -103,7 +104,9 @@
|
|||||||
.zwiico-right-dir:before { content: '\e82d'; } /* '' */
|
.zwiico-right-dir:before { content: '\e82d'; } /* '' */
|
||||||
.zwiico-chart-line:before { content: '\e82e'; } /* '' */
|
.zwiico-chart-line:before { content: '\e82e'; } /* '' */
|
||||||
.zwiico-book:before { content: '\e82f'; } /* '' */
|
.zwiico-book:before { content: '\e82f'; } /* '' */
|
||||||
|
.zwiico-square-check-empty:before { content: '\e830'; } /* '' */
|
||||||
.zwiico-spin:before { content: '\e831'; } /* '' */
|
.zwiico-spin:before { content: '\e831'; } /* '' */
|
||||||
|
.zwiico-tags:before { content: '\e832'; } /* '' */
|
||||||
.zwiico-twitter:before { content: '\f099'; } /* '' */
|
.zwiico-twitter:before { content: '\f099'; } /* '' */
|
||||||
.zwiico-facebook:before { content: '\f09a'; } /* '' */
|
.zwiico-facebook:before { content: '\f09a'; } /* '' */
|
||||||
.zwiico-docs:before { content: '\f0c5'; } /* '' */
|
.zwiico-docs:before { content: '\f0c5'; } /* '' */
|
||||||
|
BIN
core/vendor/zwiico/font/zwiico.eot
vendored
BIN
core/vendor/zwiico/font/zwiico.eot
vendored
Binary file not shown.
6
core/vendor/zwiico/font/zwiico.svg
vendored
6
core/vendor/zwiico/font/zwiico.svg
vendored
@ -8,6 +8,8 @@
|
|||||||
<missing-glyph horiz-adv-x="1000" />
|
<missing-glyph horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="plus-circled" unicode="↑" d="M420 770q174 0 297-123t123-297-123-297-297-123-297 123-123 297 123 297 297 123z m52-470l200 0 0 102-200 0 0 202-102 0 0-202-202 0 0-102 202 0 0-202 102 0 0 202z" horiz-adv-x="840" />
|
<glyph glyph-name="plus-circled" unicode="↑" d="M420 770q174 0 297-123t123-297-123-297-297-123-297 123-123 297 123 297 297 123z m52-470l200 0 0 102-200 0 0 202-102 0 0-202-202 0 0-102 202 0 0-202 102 0 0 202z" horiz-adv-x="840" />
|
||||||
|
|
||||||
|
<glyph glyph-name="square-check" unicode="" d="M0-150l0 1000 646 0-164-164-318 0 0-672 672 0 0 319 164 164 0-647-1000 0z m234 623l133 131 129-129 361 363 133-132-361-364-133-133z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
<glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
|
<glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
|
||||||
|
|
||||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||||
@ -102,8 +104,12 @@
|
|||||||
|
|
||||||
<glyph glyph-name="book" unicode="" d="M915 583q22-31 10-72l-154-505q-10-36-42-60t-69-25h-515q-43 0-83 30t-55 74q-14 37-1 71 0 2 1 15t3 20q0 5-2 12t-2 11q1 6 5 12t9 13 9 13q13 21 25 51t17 51q2 6 0 17t0 16q2 6 9 15t10 13q12 20 23 51t14 51q1 5-1 17t0 16q2 7 12 17t13 13q10 14 23 47t16 54q0 4-2 14t-1 15q1 4 5 10t10 13 10 11q4 7 9 17t8 20 9 20 11 18 15 13 20 6 26-3l0-1q21 5 28 5h425q41 0 64-32t10-72l-153-506q-20-66-40-85t-72-20h-485q-15 0-21-8-6-9-1-24 14-39 81-39h515q16 0 31 9t20 23l167 550q4 13 3 32 21-8 33-24z m-594-1q-2-7 1-12t11-6h339q8 0 15 6t9 12l12 36q2 7-1 12t-12 6h-339q-7 0-14-6t-9-12z m-46-143q-3-7 1-12t11-6h339q7 0 14 6t10 12l11 36q3 7-1 13t-11 5h-339q-7 0-14-5t-10-13z" horiz-adv-x="928.6" />
|
<glyph glyph-name="book" unicode="" d="M915 583q22-31 10-72l-154-505q-10-36-42-60t-69-25h-515q-43 0-83 30t-55 74q-14 37-1 71 0 2 1 15t3 20q0 5-2 12t-2 11q1 6 5 12t9 13 9 13q13 21 25 51t17 51q2 6 0 17t0 16q2 6 9 15t10 13q12 20 23 51t14 51q1 5-1 17t0 16q2 7 12 17t13 13q10 14 23 47t16 54q0 4-2 14t-1 15q1 4 5 10t10 13 10 11q4 7 9 17t8 20 9 20 11 18 15 13 20 6 26-3l0-1q21 5 28 5h425q41 0 64-32t10-72l-153-506q-20-66-40-85t-72-20h-485q-15 0-21-8-6-9-1-24 14-39 81-39h515q16 0 31 9t20 23l167 550q4 13 3 32 21-8 33-24z m-594-1q-2-7 1-12t11-6h339q8 0 15 6t9 12l12 36q2 7-1 12t-12 6h-339q-7 0-14-6t-9-12z m-46-143q-3-7 1-12t11-6h339q7 0 14 6t10 12l11 36q3 7-1 13t-11 5h-339q-7 0-14-5t-10-13z" horiz-adv-x="928.6" />
|
||||||
|
|
||||||
|
<glyph glyph-name="square-check-empty" unicode="" d="M0-150l0 1000 1000 0 0-1000-1000 0z m164 164l672 0 0 672-672 0 0-672z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
<glyph glyph-name="spin" unicode="" d="M46 144l0 0c0 0-1 0-1 0-8 18-15 37-21 55-6 19-11 38-15 58-19 99-8 203 35 298 3 6 10 8 15 5 1 0 2 0 2-1l0 0 80-59c5-3 6-9 4-14-5-12-9-25-12-37-4-13-7-26-9-40-11-67-3-137 23-201 2-5 0-10-4-13l0 0-80-56c-5-4-12-2-16 3-1 0-1 1-1 2l0 0z m120 574l0 0c0 1 0 1 0 1 15 13 30 25 46 37 16 11 33 22 51 31 89 50 192 72 297 60 6-1 10-6 10-13 0-1-1-1-1-2l0 0-31-94c-2-5-8-8-13-7-13 0-27 0-40 0-14-1-27-2-40-4-68-11-133-40-186-84-4-3-10-3-14 0l0 0-79 58c-5 3-6 11-2 16 0 0 1 1 2 1l0 0z m588 65l0 0c0 0 1 0 1 0 17-10 34-21 50-32 16-12 31-25 46-38 74-69 127-160 148-262 2-6-2-12-9-13-1 0-1 0-2 0l0 0-100 1c-5 0-10 4-11 9-3 13-8 26-12 38-5 12-10 25-17 36-31 61-78 113-137 150-5 3-6 8-5 13l0 0 31 92c2 6 9 9 15 7 1 0 2-1 2-1l0 0z m244-535l0 0c0 0 0 0 0 0-4-20-9-39-15-57-7-19-14-37-22-55-44-92-114-170-205-221-6-3-13-1-16 4 0 1-1 2-1 2l0 0-30 94c-2 6 1 12 6 14 11 7 22 15 32 23 11 9 21 18 30 27 49 48 84 109 101 176 2 5 6 8 11 8l0 0 98-1c6 0 11-5 11-11 0-1 0-2 0-3l0 0z m-438-395l0 0c0 0 0 0 0 0-20-2-40-3-60-3-20 0-40 1-59 4-102 12-198 54-276 125-5 4-5 11 0 16 0 0 1 1 1 1l0 0 81 58c5 3 12 2 16-2 10-8 20-16 32-23 11-7 22-14 34-20 62-31 131-45 200-41 6 0 10-3 12-8l0 0 29-92c2-6-1-12-7-14-1-1-2-1-3-1l0 0z" horiz-adv-x="1000" />
|
<glyph glyph-name="spin" unicode="" d="M46 144l0 0c0 0-1 0-1 0-8 18-15 37-21 55-6 19-11 38-15 58-19 99-8 203 35 298 3 6 10 8 15 5 1 0 2 0 2-1l0 0 80-59c5-3 6-9 4-14-5-12-9-25-12-37-4-13-7-26-9-40-11-67-3-137 23-201 2-5 0-10-4-13l0 0-80-56c-5-4-12-2-16 3-1 0-1 1-1 2l0 0z m120 574l0 0c0 1 0 1 0 1 15 13 30 25 46 37 16 11 33 22 51 31 89 50 192 72 297 60 6-1 10-6 10-13 0-1-1-1-1-2l0 0-31-94c-2-5-8-8-13-7-13 0-27 0-40 0-14-1-27-2-40-4-68-11-133-40-186-84-4-3-10-3-14 0l0 0-79 58c-5 3-6 11-2 16 0 0 1 1 2 1l0 0z m588 65l0 0c0 0 1 0 1 0 17-10 34-21 50-32 16-12 31-25 46-38 74-69 127-160 148-262 2-6-2-12-9-13-1 0-1 0-2 0l0 0-100 1c-5 0-10 4-11 9-3 13-8 26-12 38-5 12-10 25-17 36-31 61-78 113-137 150-5 3-6 8-5 13l0 0 31 92c2 6 9 9 15 7 1 0 2-1 2-1l0 0z m244-535l0 0c0 0 0 0 0 0-4-20-9-39-15-57-7-19-14-37-22-55-44-92-114-170-205-221-6-3-13-1-16 4 0 1-1 2-1 2l0 0-30 94c-2 6 1 12 6 14 11 7 22 15 32 23 11 9 21 18 30 27 49 48 84 109 101 176 2 5 6 8 11 8l0 0 98-1c6 0 11-5 11-11 0-1 0-2 0-3l0 0z m-438-395l0 0c0 0 0 0 0 0-20-2-40-3-60-3-20 0-40 1-59 4-102 12-198 54-276 125-5 4-5 11 0 16 0 0 1 1 1 1l0 0 81 58c5 3 12 2 16-2 10-8 20-16 32-23 11-7 22-14 34-20 62-31 131-45 200-41 6 0 10-3 12-8l0 0 29-92c2-6-1-12-7-14-1-1-2-1-3-1l0 0z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="tags" unicode="" d="M250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z m215 0q0-30-21-51l-274-274q-22-21-51-21-20 0-33 8t-29 25l262 262q21 21 21 51 0 29-21 50l-399 399q-21 21-57 36t-65 15h125q29 0 65-15t57-36l399-399q21-21 21-50z" horiz-adv-x="1071.4" />
|
||||||
|
|
||||||
<glyph glyph-name="twitter" unicode="" d="M904 622q-37-54-90-93 0-8 0-23 0-73-21-145t-64-139-103-117-144-82-181-30q-151 0-276 81 19-2 43-2 126 0 224 77-59 1-105 36t-64 89q19-3 34-3 24 0 48 6-63 13-104 62t-41 115v2q38-21 82-23-37 25-59 64t-22 86q0 49 25 91 68-83 164-133t208-55q-5 21-5 41 0 75 53 127t127 53q79 0 132-57 61 12 115 44-21-64-80-100 52 6 104 28z" horiz-adv-x="928.6" />
|
<glyph glyph-name="twitter" unicode="" d="M904 622q-37-54-90-93 0-8 0-23 0-73-21-145t-64-139-103-117-144-82-181-30q-151 0-276 81 19-2 43-2 126 0 224 77-59 1-105 36t-64 89q19-3 34-3 24 0 48 6-63 13-104 62t-41 115v2q38-21 82-23-37 25-59 64t-22 86q0 49 25 91 68-83 164-133t208-55q-5 21-5 41 0 75 53 127t127 53q79 0 132-57 61 12 115 44-21-64-80-100 52 6 104 28z" horiz-adv-x="928.6" />
|
||||||
|
|
||||||
<glyph glyph-name="facebook" unicode="" d="M535 843v-147h-87q-48 0-65-20t-17-60v-106h164l-22-165h-142v-424h-171v424h-142v165h142v122q0 104 58 161t155 57q82 0 127-7z" horiz-adv-x="571.4" />
|
<glyph glyph-name="facebook" unicode="" d="M535 843v-147h-87q-48 0-65-20t-17-60v-106h164l-22-165h-142v-424h-171v424h-142v165h142v122q0 104 58 161t155 57q82 0 127-7z" horiz-adv-x="571.4" />
|
||||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
BIN
core/vendor/zwiico/font/zwiico.ttf
vendored
BIN
core/vendor/zwiico/font/zwiico.ttf
vendored
Binary file not shown.
BIN
core/vendor/zwiico/font/zwiico.woff
vendored
BIN
core/vendor/zwiico/font/zwiico.woff
vendored
Binary file not shown.
BIN
core/vendor/zwiico/font/zwiico.woff2
vendored
BIN
core/vendor/zwiico/font/zwiico.woff2
vendored
Binary file not shown.
BIN
core/vendor/zwiico/fontello-2efa58ff.zip
vendored
Normal file
BIN
core/vendor/zwiico/fontello-2efa58ff.zip
vendored
Normal file
Binary file not shown.
BIN
core/vendor/zwiico/fontello-5462a440.zip
vendored
BIN
core/vendor/zwiico/fontello-5462a440.zip
vendored
Binary file not shown.
30
index.php
30
index.php
@ -14,11 +14,35 @@
|
|||||||
* @link http://zwiicms.fr/
|
* @link http://zwiicms.fr/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialisation de Zwii
|
* Initialisation de Zwii
|
||||||
*/
|
*/
|
||||||
// Remplace la directive htaccess
|
// Remplace la directive htaccess
|
||||||
ini_set('session.use_trans_sid', FALSE);
|
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
|
// Démarre la session
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
@ -34,7 +58,7 @@ include_once('core/include/checkup.php');
|
|||||||
* fr_FR.utf8 : la majorité
|
* fr_FR.utf8 : la majorité
|
||||||
*/
|
*/
|
||||||
date_default_timezone_set('Europe/Paris');
|
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
|
* Chargement des classes
|
||||||
@ -47,4 +71,4 @@ spl_autoload_register('core::autoload');
|
|||||||
* Chargement du coeur
|
* Chargement du coeur
|
||||||
*/
|
*/
|
||||||
$core = new core;
|
$core = new core;
|
||||||
echo $core->router();
|
echo $core->router();
|
@ -16,7 +16,7 @@
|
|||||||
class blog extends common
|
class blog extends common
|
||||||
{
|
{
|
||||||
|
|
||||||
const VERSION = '7.5';
|
const VERSION = '8.0';
|
||||||
const REALNAME = 'Blog';
|
const REALNAME = 'Blog';
|
||||||
const DELETE = true;
|
const DELETE = true;
|
||||||
const UPDATE = '0.0';
|
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', 'timeFormat', '%H:%M']);
|
||||||
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.5']);
|
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.5']);
|
||||||
}
|
}
|
||||||
// Version 7.4
|
// Version 8.0
|
||||||
if (version_compare($this->getData(['module', $this->getUrl(0), 'config', 'versionData']), '7.4', '<')) {
|
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', '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']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,9 +198,11 @@ class blog extends common
|
|||||||
$feeds = new \FeedWriter\RSS2();
|
$feeds = new \FeedWriter\RSS2();
|
||||||
|
|
||||||
// En-tête
|
// En-tête
|
||||||
$feeds->setTitle($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));
|
$feeds->setLink(helper::baseUrl() . $this->getUrl(0));
|
||||||
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
|
if ($this->getData(['page', $this->getUrl(0), 'metaDescription'])) {
|
||||||
|
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
|
||||||
|
}
|
||||||
$feeds->setChannelElement('language', 'fr-FR');
|
$feeds->setChannelElement('language', 'fr-FR');
|
||||||
$feeds->setDate(date('r', time()));
|
$feeds->setDate(date('r', time()));
|
||||||
$feeds->addGenerator();
|
$feeds->addGenerator();
|
||||||
@ -361,7 +365,7 @@ class blog extends common
|
|||||||
self::$dateFormat = $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat']);
|
self::$dateFormat = $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat']);
|
||||||
self::$timeFormat = $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat']);
|
self::$timeFormat = $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat']);
|
||||||
self::$comments[] = [
|
self::$comments[] = [
|
||||||
helper::dateUTF8(self::$dateFormat, $comment['createdOn']) . ' - ' . helper::dateUTF8(self::$timeFormat, $comment['createdOn']),
|
helper::dateUTF8(self::$dateFormat, $comment['createdOn'], self::$i18nUI) . ' - ' . helper::dateUTF8(self::$timeFormat, $comment['createdOn'], self::$i18nUI),
|
||||||
$comment['content'],
|
$comment['content'],
|
||||||
$comment['userId'] ? $this->getData(['user', $comment['userId'], 'firstname']) . ' ' . $this->getData(['user', $comment['userId'], 'lastname']) : $comment['author'],
|
$comment['userId'] ? $this->getData(['user', $comment['userId'], 'firstname']) . ' ' . $this->getData(['user', $comment['userId'], 'lastname']) : $comment['author'],
|
||||||
$buttonApproval,
|
$buttonApproval,
|
||||||
@ -530,7 +534,7 @@ class blog extends common
|
|||||||
'<a href="' . helper::baseurl() . $this->getUrl(0) . '/' . $articleIds[$i] . '" target="_blank" >' .
|
'<a href="' . helper::baseurl() . $this->getUrl(0) . '/' . $articleIds[$i] . '" target="_blank" >' .
|
||||||
$this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'title']) .
|
$this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'title']) .
|
||||||
'</a>',
|
'</a>',
|
||||||
helper::dateUTF8(self::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'publishedOn'])) . ' - ' . helper::dateUTF8(self::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'publishedOn'])),
|
helper::dateUTF8(self::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'publishedOn']), self::$i18nUI) . ' - ' . helper::dateUTF8(self::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'publishedOn']), self::$i18nUI),
|
||||||
self::$states[$this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'state'])],
|
self::$states[$this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'state'])],
|
||||||
// Bouton pour afficher les commentaires de l'article
|
// Bouton pour afficher les commentaires de l'article
|
||||||
template::button('blogConfigComment' . $articleIds[$i], [
|
template::button('blogConfigComment' . $articleIds[$i], [
|
||||||
@ -576,7 +580,9 @@ class blog extends common
|
|||||||
'itemsperPage' => $this->getInput('blogOptionItemsperPage', helper::FILTER_INT, true),
|
'itemsperPage' => $this->getInput('blogOptionItemsperPage', helper::FILTER_INT, true),
|
||||||
'dateFormat' => $this->getInput('blogOptionDateFormat'),
|
'dateFormat' => $this->getInput('blogOptionDateFormat'),
|
||||||
'timeFormat' => $this->getInput('blogOptionTimeFormat'),
|
'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']),
|
'versionData' => $this->getData(['module', $this->getUrl(0), 'config', 'versionData']),
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
@ -594,7 +600,6 @@ class blog extends common
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suppression
|
* Suppression
|
||||||
*/
|
*/
|
||||||
@ -747,7 +752,7 @@ class blog extends common
|
|||||||
) {
|
) {
|
||||||
// Check la captcha
|
// Check la captcha
|
||||||
if (
|
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 $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
|
and password_verify($this->getInput('blogArticleCaptcha', helper::FILTER_INT), $this->getInput('blogArticleCaptchaResult')) === false
|
||||||
) {
|
) {
|
||||||
@ -755,7 +760,7 @@ class blog extends common
|
|||||||
}
|
}
|
||||||
// Crée le commentaire
|
// Crée le commentaire
|
||||||
$commentId = helper::increment(uniqid(), $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'comment']));
|
$commentId = helper::increment(uniqid(), $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'comment']));
|
||||||
$content = $this->getInput('blogArticleContent', false);
|
$content = $this->getInput('blogArticleContent', null, true);
|
||||||
$this->setData([
|
$this->setData([
|
||||||
'module', $this->getUrl(0),
|
'module', $this->getUrl(0),
|
||||||
'posts', $this->getUrl(1),
|
'posts', $this->getUrl(1),
|
||||||
@ -829,7 +834,7 @@ class blog extends common
|
|||||||
// Signature de l'article
|
// Signature de l'article
|
||||||
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
|
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
|
||||||
// Signature du commentaire édité
|
// Signature du commentaire édité
|
||||||
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
|
if ($this->isConnected() === true) {
|
||||||
self::$editCommentSignature = $this->signature($this->getUser('id'));
|
self::$editCommentSignature = $this->signature($this->getUser('id'));
|
||||||
}
|
}
|
||||||
// Commentaires en fonction de la pagination
|
// Commentaires en fonction de la pagination
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
# 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.
|
||||||
|
# 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.
|
||||||
|
# Version 7.7
|
||||||
|
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
|
||||||
|
# Version 7.6
|
||||||
|
- Mise à jour RSS Feed
|
||||||
# Version 7.5
|
# Version 7.5
|
||||||
- Bug paramètre de localisation erroné
|
- Bug paramètre de localisation erroné
|
||||||
# Version 7.4
|
# Version 7.4
|
||||||
|
@ -1 +1 @@
|
|||||||
{"name":"blog","realName":"Blog","version":"7.2","update":"0.0","delete":true,"dataDirectory":""}
|
{"name":"blog","realName":"Blog","version":"7.12","update":"0.0","delete":true,"dataDirectory":""}
|
0
module/blog/ressource/feed-icon-16.gif
Normal file → Executable file
0
module/blog/ressource/feed-icon-16.gif
Normal file → Executable file
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 652 B |
0
module/blog/vendor/FeedWriter/ATOM.php
vendored
Normal file → Executable file
0
module/blog/vendor/FeedWriter/ATOM.php
vendored
Normal file → Executable file
74
module/blog/vendor/FeedWriter/CHANGELOG.md
vendored
Normal file
74
module/blog/vendor/FeedWriter/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Change Log
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](http://keepachangelog.com/) .
|
||||||
|
|
||||||
|
## [v1.1.2] - 2023-05-25
|
||||||
|
### Changed
|
||||||
|
- Throw an exception if required feed elements are set with ```NULL``` value. See issue #46.
|
||||||
|
|
||||||
|
## [v1.1.1] - 2016-11-19
|
||||||
|
### Changed
|
||||||
|
- Improved the documentation.
|
||||||
|
- Changed to PSR-4 autoloader in composer.json.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Item::addElement did not method chain in error conditions.
|
||||||
|
|
||||||
|
## [v1.1.0] - 2016-11-08
|
||||||
|
### Added
|
||||||
|
- Support for multiple element values.
|
||||||
|
- Support for a feed description in ATOM feeds.
|
||||||
|
- Support for ATOM feeds without ```link``` elements.
|
||||||
|
- Support for a feed image in RSS 1.0 and ATOM feeds.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- The script does now throw Exceptions instead of stopping the PHP interpreter on error conditions.
|
||||||
|
- The unique identifier for ATOM feeds / entries use the feed / entry title for generating the ID (previously the feed / entry link).
|
||||||
|
- Some URI schemes for ```Item::setId``` were wrongly allowed.
|
||||||
|
- The parameter order of the ```Feed::setImage``` method was changed.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed slow generation of the feed with huge amounts of feed entries (like 40k entries).
|
||||||
|
- Fixed PHP warning when ```Feed::setChannelAbout``` for RSS 1.0 feeds was not called.
|
||||||
|
- A feed element was generated twice if the element content & attribute value was ```NULL```.
|
||||||
|
- The detection of twice the same link with ```rel=alternate```, ```hreflang``` & ```type``` did not work.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- The deprecated method ```Item::setEnclosure``` was removed. Use ```Item::addEnclosure``` instead.
|
||||||
|
|
||||||
|
## [v1.0.4] - 2016-04-17
|
||||||
|
### Changed
|
||||||
|
- The unique identifier for ATOM feed entries is now compliant to the ATOM standard.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Filter more invalid XML chars.
|
||||||
|
- Fixed a PHP warning displayed if ```Feed::setTitle``` or ```Feed::setLink``` was not called.
|
||||||
|
|
||||||
|
## [v1.0.3] - 2015-11-11
|
||||||
|
### Added
|
||||||
|
- Method for removing tags which were CDATA encoded.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed error when the filtering of invalid XML chars failed.
|
||||||
|
- Fixed missing docblock documentation.
|
||||||
|
|
||||||
|
## [v1.0.2] - 2015-01-23
|
||||||
|
### Fixed
|
||||||
|
- Fixed a wrong docblock return data type.
|
||||||
|
|
||||||
|
## [v1.0.1] - 2014-09-21
|
||||||
|
### Fixed
|
||||||
|
- Filter invalid XML chars.
|
||||||
|
|
||||||
|
## v1.0 - 2014-09-14
|
||||||
|
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/mibe/FeedWriter/compare/v1.1.2...HEAD
|
||||||
|
[v1.1.2]: https://github.com/mibe/FeedWriter/compare/v1.1.1...v1.1.2
|
||||||
|
[v1.1.1]: https://github.com/mibe/FeedWriter/compare/v1.1.0...v1.1.1
|
||||||
|
[v1.1.0]: https://github.com/mibe/FeedWriter/compare/v1.0.4...v1.1.0
|
||||||
|
[v1.0.4]: https://github.com/mibe/FeedWriter/compare/v1.0.3...v1.0.4
|
||||||
|
[v1.0.3]: https://github.com/mibe/FeedWriter/compare/v1.0.2...v1.0.3
|
||||||
|
[v1.0.2]: https://github.com/mibe/FeedWriter/compare/v1.0.1...v1.0.2
|
||||||
|
[v1.0.1]: https://github.com/mibe/FeedWriter/compare/v1.0...v1.0.1
|
39
module/blog/vendor/FeedWriter/Feed.php
vendored
Normal file → Executable file
39
module/blog/vendor/FeedWriter/Feed.php
vendored
Normal file → Executable file
@ -2,10 +2,11 @@
|
|||||||
namespace FeedWriter;
|
namespace FeedWriter;
|
||||||
|
|
||||||
use \DateTime;
|
use \DateTime;
|
||||||
|
use \DateTimeInterface;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 Anis uddin Ahmad <anisniit@gmail.com>
|
* Copyright (C) 2008 Anis uddin Ahmad <anisniit@gmail.com>
|
||||||
* Copyright (C) 2010-2016 Michael Bemmerl <mail@mx-server.de>
|
* Copyright (C) 2010-2016, 2022 Michael Bemmerl <mail@mx-server.de>
|
||||||
*
|
*
|
||||||
* This file is part of the "Universal Feed Writer" project.
|
* This file is part of the "Universal Feed Writer" project.
|
||||||
*
|
*
|
||||||
@ -76,6 +77,13 @@ abstract class Feed
|
|||||||
*/
|
*/
|
||||||
private $version = null;
|
private $version = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the encoding of this feed.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $encoding = 'utf-8';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -87,9 +95,6 @@ abstract class Feed
|
|||||||
{
|
{
|
||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
|
|
||||||
// Setting default encoding
|
|
||||||
$this->encoding = 'utf-8';
|
|
||||||
|
|
||||||
// Setting default value for essential channel element
|
// Setting default value for essential channel element
|
||||||
$this->setTitle($version . ' Feed');
|
$this->setTitle($version . ' Feed');
|
||||||
|
|
||||||
@ -396,9 +401,13 @@ abstract class Feed
|
|||||||
* @access public
|
* @access public
|
||||||
* @param string $title value of 'title' channel tag
|
* @param string $title value of 'title' channel tag
|
||||||
* @return self
|
* @return self
|
||||||
|
* @throws \InvalidArgumentException if the title is empty or NULL.
|
||||||
*/
|
*/
|
||||||
public function setTitle($title)
|
public function setTitle($title)
|
||||||
{
|
{
|
||||||
|
if (empty($title))
|
||||||
|
throw new \InvalidArgumentException('The title may not be empty or NULL.');
|
||||||
|
|
||||||
return $this->setChannelElement('title', $title);
|
return $this->setChannelElement('title', $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,15 +415,15 @@ abstract class Feed
|
|||||||
* Set the date when the feed was lastly updated.
|
* Set the date when the feed was lastly updated.
|
||||||
*
|
*
|
||||||
* This adds the 'updated' element to the feed. The value of the date parameter
|
* This adds the 'updated' element to the feed. The value of the date parameter
|
||||||
* can be either an instance of the DateTime class, an integer containing a UNIX
|
* can be either a class implementing DateTimeInterface, an integer containing a UNIX
|
||||||
* timestamp or a string which is parseable by PHP's 'strtotime' function.
|
* timestamp or a string which is parseable by PHP's 'strtotime' function.
|
||||||
*
|
*
|
||||||
* Not supported in RSS1 feeds.
|
* Not supported in RSS1 feeds.
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param DateTime|int|string Date which should be used.
|
* @param DateTimeInterface|int|string Date which should be used.
|
||||||
* @return self
|
* @return self
|
||||||
* @throws \InvalidArgumentException if the given date is not an instance of DateTime, a UNIX timestamp or a date string.
|
* @throws \InvalidArgumentException if the given date is not an implementation of DateTimeInterface, a UNIX timestamp or a date string.
|
||||||
* @throws InvalidOperationException if this method is called on an RSS1 feed.
|
* @throws InvalidOperationException if this method is called on an RSS1 feed.
|
||||||
*/
|
*/
|
||||||
public function setDate($date)
|
public function setDate($date)
|
||||||
@ -425,7 +434,7 @@ abstract class Feed
|
|||||||
// The feeds have different date formats.
|
// The feeds have different date formats.
|
||||||
$format = $this->version == Feed::ATOM ? \DATE_ATOM : \DATE_RSS;
|
$format = $this->version == Feed::ATOM ? \DATE_ATOM : \DATE_RSS;
|
||||||
|
|
||||||
if ($date instanceof DateTime)
|
if ($date instanceof DateTimeInterface || $date instanceof DateTime)
|
||||||
$date = $date->format($format);
|
$date = $date->format($format);
|
||||||
else if(is_numeric($date) && $date >= 0)
|
else if(is_numeric($date) && $date >= 0)
|
||||||
$date = date($format, $date);
|
$date = date($format, $date);
|
||||||
@ -438,7 +447,7 @@ abstract class Feed
|
|||||||
$date = date($format, $timestamp);
|
$date = date($format, $timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new \InvalidArgumentException('The given date is not an instance of DateTime, a UNIX timestamp or a date string.');
|
throw new \InvalidArgumentException('The given date is not an implementation of DateTimeInterface, a UNIX timestamp or a date string.');
|
||||||
|
|
||||||
if ($this->version == Feed::ATOM)
|
if ($this->version == Feed::ATOM)
|
||||||
$this->setChannelElement('updated', $date);
|
$this->setChannelElement('updated', $date);
|
||||||
@ -454,9 +463,13 @@ abstract class Feed
|
|||||||
* @access public
|
* @access public
|
||||||
* @param string $description Description of the feed.
|
* @param string $description Description of the feed.
|
||||||
* @return self
|
* @return self
|
||||||
|
* @throws \InvalidArgumentException if the description is empty or NULL.
|
||||||
*/
|
*/
|
||||||
public function setDescription($description)
|
public function setDescription($description)
|
||||||
{
|
{
|
||||||
|
if (empty($description))
|
||||||
|
throw new \InvalidArgumentException('The description may not be empty or NULL.');
|
||||||
|
|
||||||
if ($this->version != Feed::ATOM)
|
if ($this->version != Feed::ATOM)
|
||||||
$this->setChannelElement('description', $description);
|
$this->setChannelElement('description', $description);
|
||||||
else
|
else
|
||||||
@ -471,9 +484,13 @@ abstract class Feed
|
|||||||
* @access public
|
* @access public
|
||||||
* @param string $link value of 'link' channel tag
|
* @param string $link value of 'link' channel tag
|
||||||
* @return self
|
* @return self
|
||||||
|
* @throws \InvalidArgumentException if the link is empty or NULL.
|
||||||
*/
|
*/
|
||||||
public function setLink($link)
|
public function setLink($link)
|
||||||
{
|
{
|
||||||
|
if (empty($link))
|
||||||
|
throw new \InvalidArgumentException('The link may not be empty or NULL.');
|
||||||
|
|
||||||
if ($this->version == Feed::ATOM)
|
if ($this->version == Feed::ATOM)
|
||||||
$this->setAtomLink($link);
|
$this->setAtomLink($link);
|
||||||
else
|
else
|
||||||
@ -667,7 +684,7 @@ abstract class Feed
|
|||||||
/**
|
/**
|
||||||
* Replace invalid XML characters.
|
* Replace invalid XML characters.
|
||||||
*
|
*
|
||||||
* @link http://www.phpwact.org/php/i18n/charsets#xml See utf8_for_xml() function
|
* @link https://web.archive.org/web/20160608013721/http://www.phpwact.org:80/php/i18n/charsets#xml See utf8_for_xml() function
|
||||||
* @link http://www.w3.org/TR/REC-xml/#charsets
|
* @link http://www.w3.org/TR/REC-xml/#charsets
|
||||||
* @link https://github.com/mibe/FeedWriter/issues/30
|
* @link https://github.com/mibe/FeedWriter/issues/30
|
||||||
*
|
*
|
||||||
@ -906,7 +923,7 @@ abstract class Feed
|
|||||||
$out .= "</rdf:Seq>" . PHP_EOL . "</items>" . PHP_EOL . "</channel>" . PHP_EOL;
|
$out .= "</rdf:Seq>" . PHP_EOL . "</items>" . PHP_EOL . "</channel>" . PHP_EOL;
|
||||||
|
|
||||||
// An image has its own element after the channel elements.
|
// An image has its own element after the channel elements.
|
||||||
if (array_key_exists('image', $this->data))
|
if (array_key_exists('Image', $this->data))
|
||||||
$out .= $this->makeNode('image', $this->data['Image'], array('rdf:about' => $this->data['Image']['url']));
|
$out .= $this->makeNode('image', $this->data['Image'], array('rdf:about' => $this->data['Image']['url']));
|
||||||
} else if ($this->version == Feed::ATOM) {
|
} else if ($this->version == Feed::ATOM) {
|
||||||
// ATOM feeds have a unique feed ID. Use the title channel element as key.
|
// ATOM feeds have a unique feed ID. Use the title channel element as key.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user