From 939cb8d53f2c039ad40374c0542e08ad6d5e51b3 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Tue, 2 Apr 2024 18:25:39 +0200 Subject: [PATCH] =?UTF-8?q?1.7.09=20r=C3=A9intalle=20la=20derni=C3=A8re=20?= =?UTF-8?q?version=20correcte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/class/jsondb/JsonDb.class.php | 73 +++------ core/class/router.class.php | 10 +- core/core.php | 231 +++++++++-------------------- core/module/config/config.php | 14 +- core/module/course/course.php | 6 +- core/module/install/install.php | 4 +- core/module/language/language.php | 8 +- core/module/plugin/plugin.php | 4 +- core/module/theme/theme.php | 8 +- 9 files changed, 120 insertions(+), 238 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index ec25e02..11223ac 100644 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -18,12 +18,6 @@ class JsonDb extends \Prowebcraft\Dot protected $db = ''; protected $data = null; protected $config = []; - // Tentative d'encodage après échec - const MAX_JSON_ENCODE_ATTEMPTS = 5; - // Tentative d'écriture après échec - const MAX_FILE_WRITE_ATTEMPTS = 5; - // Délais entre deux tentaives - const RETRY_DELAY_SECONDS = 1; public function __construct($config = []) { @@ -135,9 +129,9 @@ class JsonDb extends \Prowebcraft\Dot } } $this->data = json_decode(file_get_contents($this->db), true); - if (!$this->data === null) { - throw new \InvalidArgumentException('Database file ' . $this->db - . ' contains invalid json object. Please validate or remove file'); + if (!$this->data === null && json_last_error() !== JSON_ERROR_NONE) { + throw new \InvalidArgumentException('Le fichier ' . $this->db + . ' contient des données invalides.'); } } return $this->data; @@ -148,54 +142,25 @@ class JsonDb extends \Prowebcraft\Dot */ public function save() { - $jsonOptions = JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_FORCE_OBJECT; - $jsonData = json_encode($this->data, $jsonOptions); - - $attempts = 0; - while ($attempts < self::MAX_JSON_ENCODE_ATTEMPTS) { - if ($jsonData !== false) { - break; // Sortir de la boucle si l'encodage réussit - } - $attempts++; - error_log('Erreur d\'encodage JSON (tentative ' . $attempts . ') : ' . json_last_error_msg()); - $jsonData = json_encode($this->data, $jsonOptions); // Réessayer l'encodage - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer + $v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT); + // $v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT); + $l = strlen($v); + $t = 0; + if ($v === false) { + error_log('Erreur d\'encodage JSON : ' . json_last_error_msg()); + exit ('Erreur d\'encodage JSON : ' . json_last_error_msg()); } - - if ($jsonData === false) { - error_log('Impossible d\'encoder les données en format JSON.'); - return false; - } - $lockHandle = fopen($this->db, 'r+'); - - if (flock($lockHandle, LOCK_EX)) { - $attempts = 0; - $bytesWritten = false; - while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS && $bytesWritten === false) { - ftruncate($lockHandle, 0); // Vide le fichier - rewind($lockHandle); // Remet le pointeur au début du fichier - $bytesWritten = fwrite($lockHandle, $jsonData); - if ($bytesWritten === false) { - $attempts++; - error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données.'); - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer - } + while ($t < 5) { + $w = file_put_contents($this->db, $v); // Multi user get a locker + if ($w == $l) { + break; } - flock($lockHandle, LOCK_UN); // Libérer le verrouillage - fclose($lockHandle); // Fermer le fichier - - if ($bytesWritten === false || $bytesWritten != strlen($jsonData)) { - error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.'); - return false; - } - } else { - error_log('Impossible d\'obtenir un verrouillage sur le fichier de base de données.'); - fclose($lockHandle); // Fermer le fichier - return false; + $t++; + } + if ($w !== $l) { + error_log('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.'); } - return true; - } - } \ No newline at end of file diff --git a/core/class/router.class.php b/core/class/router.class.php index 3f31f9a..17922c2 100644 --- a/core/class/router.class.php +++ b/core/class/router.class.php @@ -61,17 +61,17 @@ class core extends common // Crée le fichier de personnalisation avancée if (file_exists(self::DATA_DIR . 'custom.css') === false) { - $this->secureFilePutContents(self::DATA_DIR . 'custom.css', 'core/module/theme/resource/custom.css'); + file_put_contents(self::DATA_DIR . 'custom.css', ('core/module/theme/resource/custom.css')); chmod(self::DATA_DIR . 'custom.css', 0755); } // Crée le fichier de personnalisation if (file_exists(self::DATA_DIR . self::$siteContent . '/theme.css') === false) { - $this->secureFilePutContents(self::DATA_DIR . self::$siteContent . '/theme.css', ''); + file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', ''); chmod(self::DATA_DIR . self::$siteContent . '/theme.css', 0755); } // Crée le fichier de personnalisation de l'administration if (file_exists(self::DATA_DIR . 'admin.css') === false) { - $this->secureFilePutContents(self::DATA_DIR . 'admin.css', ''); + file_put_contents(self::DATA_DIR . 'admin.css', ''); chmod(self::DATA_DIR . 'admin.css', 0755); } @@ -273,7 +273,7 @@ class core extends common $css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}'; // Enregistre la personnalisation - $this->secureFilePutContents(self::DATA_DIR . self::$siteContent . '/theme.css', $css); + file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', $css); // Effacer le cache pour tenir compte de la couleur de fond TinyMCE header("Expires: Tue, 01 Jan 2000 00:00:00 GMT"); @@ -368,7 +368,7 @@ class core extends common // Bordure du contour TinyMCE $css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}'; // Enregistre la personnalisation - $this->secureFilePutContents(self::DATA_DIR . 'admin.css', $css); + file_put_contents(self::DATA_DIR . 'admin.css', $css); } } /** diff --git a/core/core.php b/core/core.php index 8889991..41aff3a 100644 --- a/core/core.php +++ b/core/core.php @@ -51,7 +51,7 @@ class common const ACCESS_TIMER = 1800; // Numéro de version - const ZWII_VERSION = '1.7.09'; + const ZWII_VERSION = '1.7.08'; // URL autoupdate const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/campus-update/raw/branch/master/'; @@ -72,18 +72,6 @@ class common const COURSE_ENROLMENT_SELF_KEY = 2; // Ouvert à tous les membres disposant de la clé const COURSE_ENROLMENT_MANDATORY = 3; - const MAX_FILE_WRITE_ATTEMPTS = 5; - - /** - * Nombre maximal de tentatives d'encodage JSON - */ - const MAX_JSON_ENCODE_ATTEMPTS = 3; - - /** - * Temps d'attente entre les tentatives en secondes - */ - const RETRY_DELAY_SECONDS = 1; - public static $actions = []; public static $coreModuleIds = [ @@ -347,11 +335,11 @@ class common // Instanciation de la classe des entrées / sorties // Les fichiers de configuration foreach ($this->configFiles as $module => $value) { - $this->initDB($module, self::DATA_DIR); + $this->initDB($module); } // Les fichiers des contenus foreach ($this->contentFiles as $module => $value) { - $this->initDB($module, self::DATA_DIR . self::$siteContent . '/'); + $this->initDB($module, self::$siteContent); } @@ -459,7 +447,7 @@ class common } // Mise à jour des données core - include ('core/include/update.inc.php'); + include('core/include/update.inc.php'); } @@ -607,7 +595,7 @@ class common public function setPage($page, $value, $path) { - return $this->secureFilePutContents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value); + return file_put_contents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value); } @@ -623,13 +611,13 @@ class common } - public function initDB($module, $path) + public function initDB($module, $path = '') { // Instanciation de la classe des entrées / sorties // Constructeur JsonDB; $this->dataFiles[$module] = new \Prowebcraft\JsonDb([ 'name' => $module . '.json', - 'dir' => $path, + 'dir' => self::DATA_DIR . $path . '/', 'backup' => file_exists('site/data/.backup') ]); @@ -646,7 +634,7 @@ class common { // Tableau avec les données vierges - require_once ('core/module/install/ressource/defaultdata.php'); + require_once('core/module/install/ressource/defaultdata.php'); // L'arborescence if (!file_exists(self::DATA_DIR . $path)) { @@ -681,7 +669,7 @@ class common public function saveConfig($module) { // Tableau avec les données vierges - require_once ('core/module/install/ressource/defaultdata.php'); + require_once('core/module/install/ressource/defaultdata.php'); // Installation des données des autres modules cad theme profil font config, admin et core $this->setData([$module, init::$defaultData[$module]]); common::$coreNotices[] = $module; @@ -717,136 +705,65 @@ class common * Fonction pour construire le tableau des pages */ - private function buildHierarchy() - { - - $pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC'); - // Parents - foreach ($pages as $pageId => $pagePosition) { - if ( - // Page parent - $this->getData(['page', $pageId, 'parentPageId']) === "" - // Ignore les pages dont l'utilisateur n'a pas accès - and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR - or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') - //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group']) - // Modification qui tient compte du profil de la page - and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])) - - ) - ) - ) { - if ($pagePosition !== 0) { - $this->hierarchy['visible'][$pageId] = []; - } - if ($this->getData(['page', $pageId, 'block']) === 'bar') { - $this->hierarchy['bar'][$pageId] = []; - } - $this->hierarchy['all'][$pageId] = []; - } - } - // Enfants - foreach ($pages as $pageId => $pagePosition) { - - if ( - // Page parent - $parentId = $this->getData(['page', $pageId, 'parentPageId']) - // Ignore les pages dont l'utilisateur n'a pas accès - and ( - ( - $this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR - and - $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR - ) - or ( - $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') - and - $this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']) - - ) - ) - ) { - if ($pagePosition !== 0) { - $this->hierarchy['visible'][$parentId][] = $pageId; - } - if ($this->getData(['page', $pageId, 'block']) === 'bar') { - $this->hierarchy['bar'][$pageId] = []; - } - $this->hierarchy['all'][$parentId][] = $pageId; - } - } - } - - /** - * Nombre maximal de tentatives d'écriture dans le fichier - */ - - - /** - * Écriture sécurisée dans un fichier en utilisant un verrouillage de fichier pour éviter les accès concurrents. - * Les données sont encodées au format JSON si l'extension du fichier est JSON. - * - * @param string $filename Le chemin du fichier dans lequel écrire les données. - * @param mixed $data Les données à écrire dans le fichier. - * @param int $options Les options pour la fonction file_put_contents, par défaut 0. - * - * @return bool Retourne true si l'écriture dans le fichier est réussie, false sinon. - */ - public static function secureFilePutContents($filename, $data, $options = 0) - { - // Vérifier si l'extension du fichier est JSON - $extension = pathinfo($filename, PATHINFO_EXTENSION); - $encodeJson = strtolower($extension) === 'json'; - - // Tentatives d'encodage JSON si nécessaire - if ($encodeJson) { - $jsonData = null; - $attempts = 0; - while ($attempts < self::MAX_JSON_ENCODE_ATTEMPTS) { - $jsonData = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - if ($jsonData !== false) { - break; // Sortir de la boucle si l'encodage réussit - } - $attempts++; - error_log('Erreur d\'encodage JSON (tentative ' . $attempts . ') : ' . json_last_error_msg()); - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer - } - - if ($jsonData === false) { - error_log('Impossible d\'encoder les données en format JSON.'); - return false; - } - } else { - // Pas d'encodage JSON nécessaire - $jsonData = $data; - } - - // Écriture sécurisée dans le fichier avec un verrouillage - $attempts = 0; - while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS) { - $lockHandle = fopen($filename, 'c+'); - if ($lockHandle !== false && flock($lockHandle, LOCK_EX)) { - $bytesWritten = fwrite($lockHandle, $jsonData); - if ($bytesWritten !== false && $bytesWritten === strlen($jsonData)) { - fflush($lockHandle); // Vider le tampon - ftruncate($lockHandle, ftell($lockHandle)); // Tronquer le fichier à la position actuelle du pointeur - flock($lockHandle, LOCK_UN); // Libérer le verrouillage - fclose($lockHandle); // Fermer le fichier - return file_put_contents($filename, $jsonData, $options) !== false; // Écriture réussie - } - flock($lockHandle, LOCK_UN); // Libérer le verrouillage en cas d'échec d'écriture - } - if ($lockHandle !== false) { - fclose($lockHandle); // Fermer le fichier en cas d'échec d'acquisition du verrouillage - } - $attempts++; - error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données dans ' . $filename); - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer - } - - error_log('Impossible d\'écrire dans le fichier ' . $filename . ' après ' . self::MAX_FILE_WRITE_ATTEMPTS . ' tentatives.'); - return false; - } + private function buildHierarchy() + { + + $pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC'); + // Parents + foreach ($pages as $pageId => $pagePosition) { + if ( + // Page parent + $this->getData(['page', $pageId, 'parentPageId']) === "" + // Ignore les pages dont l'utilisateur n'a pas accès + and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR + or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') + //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group']) + // Modification qui tient compte du profil de la page + and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])) + + ) + ) + ) { + if ($pagePosition !== 0) { + $this->hierarchy['visible'][$pageId] = []; + } + if ($this->getData(['page', $pageId, 'block']) === 'bar') { + $this->hierarchy['bar'][$pageId] = []; + } + $this->hierarchy['all'][$pageId] = []; + } + } + // Enfants + foreach ($pages as $pageId => $pagePosition) { + + if ( + // Page parent + $parentId = $this->getData(['page', $pageId, 'parentPageId']) + // Ignore les pages dont l'utilisateur n'a pas accès + and ( + ( + $this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR + and + $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR + ) + or ( + $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') + and + $this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']) + + ) + ) + ) { + if ($pagePosition !== 0) { + $this->hierarchy['visible'][$parentId][] = $pageId; + } + if ($this->getData(['page', $pageId, 'block']) === 'bar') { + $this->hierarchy['bar'][$pageId] = []; + } + $this->hierarchy['all'][$parentId][] = $pageId; + } + } + } /** * Génère un fichier json avec la liste des pages @@ -909,7 +826,7 @@ class common // Enregistrement : 3 tentatives for ($i = 0; $i < 3; $i++) { - if ($this->secureFilePutContents('core/vendor/tinymce/link_list.json', json_encode($parents, JSON_UNESCAPED_UNICODE), LOCK_EX) !== false) { + if (file_put_contents('core/vendor/tinymce/link_list.json', json_encode($parents, JSON_UNESCAPED_UNICODE), LOCK_EX) !== false) { break; } // Pause de 10 millisecondes @@ -1201,7 +1118,7 @@ class common } $sitemap->updateRobots(); } else { - $this->secureFilePutContents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /'); + file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /'); } // Submit your sitemaps to Google, Yahoo, Bing and Ask.com @@ -1491,7 +1408,7 @@ class common $dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl(); $dataLog .= PHP_EOL; if ($this->getData(['config', 'connect', 'log'])) { - $this->secureFilePutContents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); + file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); } } @@ -1518,8 +1435,8 @@ class common foreach ($courses as $courseId => $value) { // Affiche les espaces gérés par l'éditeur, les espaces où il participe et les espaces anonymes if ( - // le membre est inscrit - ($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId]))) + // le membre est inscrit + ( $this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) ) // Il est l'auteur || $this->getUser('id') === $this->getData(['course', $courseId, 'author']) // Le cours est ouvert @@ -1533,7 +1450,7 @@ class common foreach ($courses as $courseId => $value) { // Affiche les espaces du participant et les espaces anonymes 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 ) { $filter[$courseId] = $courses[$courseId]; diff --git a/core/module/config/config.php b/core/module/config/config.php index 88e3085..bcc4134 100644 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -567,7 +567,7 @@ class config extends common '' . PHP_EOL . '# URL rewriting' . PHP_EOL; $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); - $this->secureFilePutContents( + file_put_contents( '.htaccess', $fileContent ); @@ -583,7 +583,7 @@ class config extends common $fileContent = file_get_contents('.htaccess'); $fileContent = explode('# URL rewriting', $fileContent); $fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2]; - $this->secureFilePutContents( + file_put_contents( '.htaccess', $fileContent ); @@ -709,10 +709,10 @@ class config extends common ) { // Ecrire les fichiers de script if ($this->geturl(2) === 'head') { - $this->secureFilePutContents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null)); + file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null)); } if ($this->geturl(2) === 'body') { - $this->secureFilePutContents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null)); + file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null)); } // Valeurs en sortie $this->addOutput([ @@ -754,7 +754,7 @@ class config extends common unlink(self::DATA_DIR . 'journal.log'); // Créer les en-têtes des journaux $d = 'Date;Heure;IP;Id;Action' . PHP_EOL; - $this->secureFilePutContents(self::DATA_DIR . 'journal.log', $d); + file_put_contents(self::DATA_DIR . 'journal.log', $d); // Valeurs en sortie $this->addOutput([ 'title' => helper::translate('Configuration'), @@ -830,7 +830,7 @@ class config extends common ob_start(); $fileName = self::TEMP_DIR . 'blacklist.log'; $d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL; - $this->secureFilePutContents($fileName, $d); + file_put_contents($fileName, $d); if (file_exists($fileName)) { $d = $this->getData(['blacklist']); $data = ''; @@ -838,7 +838,7 @@ class config extends common $data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nUI) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nUI); $data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL; } - $this->secureFilePutContents($fileName, $data, FILE_APPEND); + file_put_contents($fileName, $data, FILE_APPEND); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Transfer-Encoding: binary'); diff --git a/core/module/course/course.php b/core/module/course/course.php index 77904eb..cc4d2bd 100644 --- a/core/module/course/course.php +++ b/core/module/course/course.php @@ -1597,17 +1597,17 @@ class course extends common // Participants avec historiques $enrolment = $this->getData(['enrolment', $courseId]); // Générer un fichier dans le dossier de l'espace - $this->secureFilePutContents(self::DATA_DIR . $courseId . '/enrolment.json', [$courseId => $enrolment]); + 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 $course = $this->getData(['course', $courseId]); // Générer un fichier dans le dossier de l'espace - $this->secureFilePutContents(self::DATA_DIR . $courseId . '/course.json',[$courseId => $course]); + 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 $category = $this->getData(['category', $this->getData(['course', $courseId, 'category'])]); // Générer un fichier dans le dossier de l'espace - $this->secureFilePutContents(self::DATA_DIR . $courseId . '/category.json', [$this->getData(['course', $courseId, 'category']) => $category]); + 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 diff --git a/core/module/install/install.php b/core/module/install/install.php index d3f9d60..23e455a 100644 --- a/core/module/install/install.php +++ b/core/module/install/install.php @@ -278,7 +278,7 @@ class install extends common case 2: $success = true; $message = ''; - $this->secureFilePutContents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')); + file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')); $md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5'); $md5origin = explode(' ', $md5origin); $md5target = md5_file(self::TEMP_DIR . 'update.tar.gz'); @@ -387,7 +387,7 @@ class install extends common '' . PHP_EOL . '# URL rewriting' . PHP_EOL; $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); - $success = $this->secureFilePutContents( + $success = file_put_contents( '.htaccess', $fileContent ); diff --git a/core/module/language/language.php b/core/module/language/language.php index fea4c43..b6b3d9f 100644 --- a/core/module/language/language.php +++ b/core/module/language/language.php @@ -99,7 +99,7 @@ class language extends common is_array($descripteur['language'][$lang]) ) { if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) { - $success = $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $languageData); + $success = 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; } } @@ -419,7 +419,7 @@ class language extends common $this->setData(['locale', $data['locale']]); } else { // Sauver sur le disque - $this->secureFilePutContents(self::DATA_DIR . $lang . '/locale.json', $data); + file_put_contents(self::DATA_DIR . $lang . '/locale.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); } // Valeurs en sortie @@ -501,7 +501,7 @@ class language extends common $data[$key] = $target; } } - $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $data); + file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); // Mettre à jour le descripteur $this->setData([ @@ -535,7 +535,7 @@ class language extends common $data[$key] = ''; } } - $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $data); + file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); // Tableau des chaines à traduire dans la langue sélectionnée foreach ($data as $key => $value) { diff --git a/core/module/plugin/plugin.php b/core/module/plugin/plugin.php index f0a65a0..dd7958f 100644 --- a/core/module/plugin/plugin.php +++ b/core/module/plugin/plugin.php @@ -317,7 +317,7 @@ class plugin extends common mkdir(self::FILE_DIR . 'source/modules', 0755); } // Sauver les données du fichiers - $this->secureFilePutContents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData); + file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData); // Installation directe if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) { @@ -597,7 +597,7 @@ class plugin extends common $fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip'; // Régénération du descripteur du module - $this->secureFilePutContents(self::MODULE_DIR . $moduleId . '/enum.json',$infoModule[$moduleId]); + file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId], JSON_UNESCAPED_UNICODE)); // Construire l'archive $this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId); diff --git a/core/module/theme/theme.php b/core/module/theme/theme.php index 6753de9..50298cc 100644 --- a/core/module/theme/theme.php +++ b/core/module/theme/theme.php @@ -304,7 +304,7 @@ class theme extends common $this->isPost() ) { // Enregistre le CSS - $this->secureFilePutContents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null)); + file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null)); // Valeurs en sortie $this->addOutput([ 'notification' => helper::translate('Modifications enregistrées'), @@ -1305,7 +1305,7 @@ class theme extends common } // Sauvegarder la chaîne modifiée if ($count > 0) { - $this->secureFilePutContents($file, $data); + file_put_contents($file, $data); } // Retourner le nombre d'occurrences return ($count); @@ -1411,8 +1411,8 @@ class theme extends common } // Enregistre la personnalisation - $this->secureFilePutContents(self::DATA_DIR . 'font/font.html', $fileContent); + file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent); // Enregistre la personnalisation - $this->secureFilePutContents(self::DATA_DIR . 'font/font.css', $fileContentCss); + file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss); } } \ No newline at end of file