This commit is contained in:
Fred Tempez 2024-09-28 13:24:55 +02:00
parent 8dc1adc28a
commit dc81614114
5 changed files with 101 additions and 77 deletions

View File

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

View File

@ -423,7 +423,7 @@ class core extends common
)
) {
// Stocke la dernière page vue et sa date de consultation
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)]);
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'lastPageView', $this->getUrl(0)], false);
$this->setData(['enrolment', common::$siteContent, $this->getUser('id'), 'datePageView', time()]);
// Stocke le rapport en CSV
@ -541,7 +541,7 @@ class core extends common
$this->isConnected() === true
&& $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()]);
}
// Breadcrumb

View File

@ -51,7 +51,7 @@ class common
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '1.12.00.15';
const ZWII_VERSION = '1.13.00';
// URL autoupdate
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);
}
/**
* Sauvegarde des données
* @param array $keys Clé(s) des données
*/
public function setData($keys = [])
{
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
if (
!empty(self::$inputNotices)
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;
/**
* Sauvegarde des données
* @param array $keys Clé(s) des données
* @param bool $save Indique si le fichier doit être sauvegardé après modification (par défaut true)
* @return bool Succès de l'opération
*/
public function setData($keys = [], $save = true)
{
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
if (
!empty(self::$inputNotices)
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], $save));
}
return $success;
}
/**
* Accède aux données
* @param array $keys Clé(s) des données
@ -656,16 +659,33 @@ class common
public function initDB($module, $path = '')
{
// Instanciation de la classe des entrées / sorties
// Constructeur JsonDB;
$this->dataFiles[$module] = new \Prowebcraft\JsonDb([
// Chemin complet vers le fichier JSON
$dir = empty($path) ? self::DATA_DIR : self::DATA_DIR . $path . '/';
$config = [
'name' => $module . '.json',
'dir' => empty($path) ? self::DATA_DIR : self::DATA_DIR . $path . '/',
'backup' => file_exists('site/data/.backup')
]);
'dir' => $dir,
'backup' => file_exists('site/data/.backup'),
'update' => false,
];
// Instanciation de l'objet et stockage dans dataFiles
$this->dataFiles[$module] = new \Prowebcraft\JsonDb($config);
}
/**
* Cette fonction est liée à saveData
* @param mixed $module
* @return void
*/
public function saveDB($module): void
{
$db = $this->dataFiles[$module];
$db->save();
}
/**
* Initialisation des données sur un contenu ou la page d'accueil
* @param string $course : id du module à générer

View File

@ -798,9 +798,11 @@ class course extends common
$this->getData(['user', $keyPost]) !== null
&& $this->getData(['enrolment', $courseId, $keyPost]) === null
) {
$this->setData(['enrolment', $courseId, $keyPost, 'history', array()]);
$this->setData(['enrolment', $courseId, $keyPost, 'history', array()], false);
}
}
// Sauvegarde la base manuellement
$this->saveDB('enrolment');
}
// Liste des groupes et des profils
@ -1154,11 +1156,6 @@ class course extends common
? helper::baseUrl() . $this->getData(['enrolment', $courseId, $userId, 'lastPageView'])
: helper::baseUrl();
/*
$essage = $this->getData(['enrolment', $courseId, $userId, 'datePageView'])
? $this->getData(['enrolment', $courseId, $userId, 'datePageView'])
: '';
*/
if ($this->getData(['course', $courseId, 'access']) === self::COURSE_ACCESS_DATE) {
$to = helper::dateUTF8('%d %B %Y', $this->getData(['course', $courseId, 'closingDate']), self::$i18nUI) . helper::translate(' à ') . helper::dateUTF8('%H:%M', $this->getData(['course', $courseId, 'closingDate']), self::$i18nUI);
$message .= sprintf(helper::translate('Ce contenu ferme le %s'), $to);
@ -1390,7 +1387,7 @@ class course extends common
if (!empty($userValue['history'])) {
$maxTime = max($userValue['history']);
$lastPageId = array_search($maxTime, $userValue['history']);
$this->setData(['enrolment', $courseId, $userId, 'lastPageView', $lastPageId]);
$this->setData(['enrolment', $courseId, $userId, 'lastPageView', $lastPageId], false);
$this->setData(['enrolment', $courseId, $userId, 'datePageView', $maxTime]);
}
}

View File

@ -428,7 +428,8 @@ class user extends common
if ($this->getUser('group') < self::GROUP_ADMIN) {
if ($this->getInput('userEditNewPassword')) {
// L'ancien mot de passe est correct
if (password_verify(html_entity_decode($this->getInput('userEditOldPassword')), $this->getData(['user', $this->getUrl(2), 'password']))
if (
password_verify(html_entity_decode($this->getInput('userEditOldPassword')), $this->getData(['user', $this->getUrl(2), 'password']))
) {
// La confirmation correspond au mot de passe
if ($this->getInput('userEditNewPassword') === $this->getInput('userEditConfirmPassword')) {
@ -1149,12 +1150,12 @@ class user extends common
// Exclure les espaces des cours
/*
foreach (array_keys($this->getData(['course'])) as $courseId) {
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
return strpos($key, $courseId) === false;
});
}
*/
foreach (array_keys($this->getData(['course'])) as $courseId) {
self::$sharePath = array_filter(self::$sharePath, function ($key) use ($courseId) {
return strpos($key, $courseId) === false;
});
}
*/
self::$sharePath = array_flip(self::$sharePath);
self::$sharePath = array_merge(['none' => 'Aucun Accès'], self::$sharePath);
@ -1261,7 +1262,7 @@ class user extends common
'lastFail' => time(),
'ip' => helper::getIp()
]
]);
], false);
// Verrouillage des IP
$ipBlackList = helper::arrayColumn($this->getData(['blacklist']), 'ip');
if (
@ -1290,8 +1291,8 @@ class user extends common
$this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
and $this->getData(['user', $userId, 'connectFail']) === $this->getData(['config', 'connect', 'attempt'])
) {
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
}
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
// Vérification du mot de passe et du groupe
@ -1303,12 +1304,12 @@ class user extends common
and $captcha === true
) {
// RAZ
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
// Clé d'authenfication
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
$this->setData(['user', $userId, 'authKey', $authKey]);
$this->setData(['user', $userId, 'authKey', $authKey], false);
// Validité du cookie
$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
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']]);
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']], false);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if (
$this->getData(['config', 'maintenance'])
@ -1366,11 +1367,11 @@ class user extends common
$logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha';
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
if ($this->getData(['user', $userId, 'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1]);
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1], false);
}
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
if ($this->getdata(['user', $userId, 'connectFail']) == $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectTimeout', time()]);
$this->setData(['user', $userId, 'connectTimeout', time()], false);
}
// Cas 3 le délai de bloquage court
if ($this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time()) {
@ -1384,9 +1385,13 @@ class user extends common
}
}
}
// Journalisation
$this->saveLog($logStatus);
// Sauvegarde la base manuellement
$this->saveDB('user');
// Stockage des cookies
if (!empty($_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);
}
// Modifie le mot de passe
$this->setData(['user', $this->getUrl(2), 'password', $newPassword]);
$this->setData(['user', $this->getUrl(2), 'password', $newPassword], false);
// Réinitialise la date de la demande
$this->setData(['user', $this->getUrl(2), 'forgot', 0]);
$this->setData(['user', $this->getUrl(2), 'forgot', 0], false);
// Réinitialise le blocage
$this->setData(['user', $this->getUrl(2), 'connectFail', 0]);
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0]);
$this->setData(['user', $this->getUrl(2), 'connectFail', 0], false);
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0], false);
// Sauvegarde la base manuellement
$this->saveDB('user');
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Nouveau mot de passe enregistré'),