init WIP
This commit is contained in:
parent
8dc1adc28a
commit
dc81614114
@ -156,21 +156,21 @@ class JsonDb extends \Prowebcraft\Dot
|
|||||||
// Essaye d'écrire les données encodées dans le fichier de base de données
|
// 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
|
$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
|
// Vérifie si l'écriture a réussi
|
||||||
if ($write_result === $encoded_length) {
|
if ($write_result === $encoded_length) {
|
||||||
// Sort de la boucle si l'écriture a réussi
|
// Sort de la boucle si l'écriture a réussi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrémente le compteur de tentatives
|
// Incrémente le compteur de tentatives
|
||||||
$attempt++;
|
$attempt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifie si l'écriture a échoué même après plusieurs tentatives
|
// Vérifie si l'écriture a échoué même après plusieurs tentatives
|
||||||
if ($write_result !== $encoded_length) {
|
if ($write_result !== $encoded_length) {
|
||||||
// Enregistre un message d'erreur dans le journal des erreurs
|
// Enregistre un message d'erreur dans le journal des erreurs
|
||||||
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
|
||||||
|
|
||||||
// Affiche un message d'erreur et termine le script
|
// 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.');
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ class core extends common
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// 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', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)]);
|
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)], false);
|
||||||
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'datePageView', time()]);
|
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'datePageView', time()]);
|
||||||
|
|
||||||
// Stocke le rapport en CSV
|
// Stocke le rapport en CSV
|
||||||
@ -541,7 +541,7 @@ class core extends common
|
|||||||
$this->isConnected() === true
|
$this->isConnected() === true
|
||||||
&& $this->getUser('id')
|
&& $this->getUser('id')
|
||||||
) {
|
) {
|
||||||
$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
|
||||||
|
104
core/core.php
104
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.12.00.15';
|
const ZWII_VERSION = '1.13.00';
|
||||||
|
|
||||||
// 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/';
|
||||||
@ -511,43 +511,46 @@ class common
|
|||||||
return is_object($success);
|
return is_object($success);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
public function setData($keys = [])
|
* @return bool Succès de l'opération
|
||||||
{
|
*/
|
||||||
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
|
public function setData($keys = [], $save = true)
|
||||||
if (
|
{
|
||||||
!empty(self::$inputNotices)
|
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
|
||||||
or empty($keys)
|
if (
|
||||||
) {
|
!empty(self::$inputNotices)
|
||||||
return false;
|
or empty($keys)
|
||||||
}
|
) {
|
||||||
|
return false;
|
||||||
// Empêcher la sauvegarde d'une donnée nulle.
|
|
||||||
if (gettype($keys[count($keys) - 1]) === NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialisation du retour en cas d'erreur de descripteur
|
|
||||||
$success = false;
|
|
||||||
// Construire la requête dans la base inf à 1 retourner toute la base
|
|
||||||
if (count($keys) >= 1) {
|
|
||||||
// Descripteur de la base
|
|
||||||
$db = $this->dataFiles[$keys[0]];
|
|
||||||
$query = $keys[0];
|
|
||||||
// Construire la requête
|
|
||||||
// Ne pas tenir compte du dernier élément qui une une value donc <
|
|
||||||
for ($i = 1; $i < count($keys) - 1; $i++) {
|
|
||||||
$query .= '.' . $keys[$i];
|
|
||||||
}
|
|
||||||
// Appliquer la modification, le dernier élément étant la donnée à sauvegarder
|
|
||||||
$success = is_object($db->set($query, $keys[count($keys) - 1], true));
|
|
||||||
}
|
|
||||||
return $success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Empêcher la sauvegarde d'une donnée nulle.
|
||||||
|
if (gettype($keys[count($keys) - 1]) === NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisation du retour en cas d'erreur de descripteur
|
||||||
|
$success = false;
|
||||||
|
// Construire la requête dans la base inf à 1 retourner toute la base
|
||||||
|
if (count($keys) >= 1) {
|
||||||
|
// Descripteur de la base
|
||||||
|
$db = $this->dataFiles[$keys[0]];
|
||||||
|
$query = $keys[0];
|
||||||
|
// Construire la requête
|
||||||
|
// Ne pas tenir compte du dernier élément qui une une value donc <
|
||||||
|
for ($i = 1; $i < count($keys) - 1; $i++) {
|
||||||
|
$query .= '.' . $keys[$i];
|
||||||
|
}
|
||||||
|
// Appliquer la modification, le dernier élément étant la donnée à sauvegarder
|
||||||
|
$success = is_object($db->set($query, $keys[count($keys) - 1], $save));
|
||||||
|
}
|
||||||
|
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
|
||||||
@ -656,15 +659,32 @@ class common
|
|||||||
|
|
||||||
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' => empty($path) ? self::DATA_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
|
||||||
|
@ -798,9 +798,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
|
||||||
@ -1154,11 +1156,6 @@ class course extends common
|
|||||||
? 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);
|
||||||
@ -1390,7 +1387,7 @@ 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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,7 +428,8 @@ 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')) {
|
||||||
@ -1149,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);
|
||||||
@ -1261,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 (
|
||||||
@ -1290,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
|
||||||
@ -1303,12 +1304,12 @@ 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);
|
||||||
|
|
||||||
// Clé d'authenfication
|
// Clé d'authenfication
|
||||||
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
|
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
|
||||||
$this->setData(['user', $userId, 'authKey', $authKey]);
|
$this->setData(['user', $userId, 'authKey', $authKey], false);
|
||||||
|
|
||||||
// Validité du cookie
|
// 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;
|
||||||
@ -1332,7 +1333,7 @@ class user extends common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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'])
|
||||||
@ -1366,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()) {
|
||||||
@ -1384,9 +1385,13 @@ class user extends common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Journalisation
|
// Journalisation
|
||||||
$this->saveLog($logStatus);
|
$this->saveLog($logStatus);
|
||||||
|
|
||||||
|
// Sauvegarde la base manuellement
|
||||||
|
$this->saveDB('user');
|
||||||
|
|
||||||
// Stockage des cookies
|
// Stockage des cookies
|
||||||
if (!empty($_COOKIE['ZWII_USER_ID'])) {
|
if (!empty($_COOKIE['ZWII_USER_ID'])) {
|
||||||
self::$userId = $_COOKIE['ZWII_USER_ID'];
|
self::$userId = $_COOKIE['ZWII_USER_ID'];
|
||||||
@ -1461,12 +1466,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é'),
|
||||||
@ -1691,7 +1698,7 @@ class user extends common
|
|||||||
$this->getData(['user', $keyPost]) !== null
|
$this->getData(['user', $keyPost]) !== null
|
||||||
) {
|
) {
|
||||||
$this->setData(['user', $keyPost, 'tags', $newTags]);
|
$this->setData(['user', $keyPost, 'tags', $newTags]);
|
||||||
$count += 1;
|
$count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Valeurs en sortie
|
// Valeurs en sortie
|
||||||
@ -1702,7 +1709,7 @@ class user extends common
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Liste des groupes et des profils
|
// Liste des groupes et des profils
|
||||||
$usersGroups = $this->getData(['profil']);
|
$usersGroups = $this->getData(['profil']);
|
||||||
|
Loading…
Reference in New Issue
Block a user