aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2026-05-19 00:19:23 +0200
committerpolo <ordipolo@gmx.fr>2026-05-19 00:19:23 +0200
commitac78568e1c1a91564eb6bd35c03d9a8a781bc53d (patch)
tree11deab2f8b82c30110faa4329be7c14f2ba394c1
parente79931432e63a86c5b7ced8a41186a24239794fe (diff)
downloadcms-ac78568e1c1a91564eb6bd35c03d9a8a781bc53d.tar.gz
cms-ac78568e1c1a91564eb6bd35c03d9a8a781bc53d.tar.bz2
cms-ac78568e1c1a91564eb6bd35c03d9a8a781bc53d.zip
lancés et captures d'exceptions page maintenance, page menu et chemins: interdiction pour une page d'avoir pour parent une adresse d'un site, regression contructeur de MenuBuilder, MAJ de paquets dans composer.json
-rw-r--r--composer.json12
-rw-r--r--public/js/maintenance.js22
-rw-r--r--public/js/menu.js9
-rw-r--r--src/controller/MaintenanceController.php6
-rw-r--r--src/controller/MenuAndPathsController.php8
-rw-r--r--src/controller/UserController.php8
-rw-r--r--src/service/Backup.php16
-rw-r--r--src/view/MaintenanceBuilder.php9
-rw-r--r--src/view/MenuBuilder.php6
-rw-r--r--src/view/templates/menu.php2
10 files changed, 72 insertions, 26 deletions
diff --git a/composer.json b/composer.json
index 8d97d87..b7ad2e5 100644
--- a/composer.json
+++ b/composer.json
@@ -2,17 +2,17 @@
2 "name": "ordipolo/cms", 2 "name": "ordipolo/cms",
3 "description": "CMS maison avec PHP, doctrine et tinyMCE", 3 "description": "CMS maison avec PHP, doctrine et tinyMCE",
4 "require": { 4 "require": {
5 "composer": "*",
5 "doctrine/dbal": "^4.3", 6 "doctrine/dbal": "^4.3",
6 "doctrine/orm": "^3.5", 7 "doctrine/orm": "^3.5",
7 "symfony/cache": "^7.3", 8 "symfony/cache": "^7.0",
8 "composer": "*",
9 "htmlawed/htmlawed": "^1.2", 9 "htmlawed/htmlawed": "^1.2",
10 "tinymce/tinymce": "^8.2", 10 "tinymce/tinymce": "^8.5",
11 "phpmailer/phpmailer": "^7.0", 11 "mklkj/tinymce-i18n": "^26.5",
12 "symfony/http-foundation": "^7.3", 12 "phpmailer/phpmailer": "^7.1",
13 "twbs/bootstrap-icons": "^1.13", 13 "twbs/bootstrap-icons": "^1.13",
14 "symfony/http-foundation": "^7.0",
14 "symfony/var-exporter": "^7.0", 15 "symfony/var-exporter": "^7.0",
15 "mklkj/tinymce-i18n": "^25.11",
16 "symfony/process": "^7.0" 16 "symfony/process": "^7.0"
17 }, 17 },
18 "scripts": { 18 "scripts": {
diff --git a/public/js/maintenance.js b/public/js/maintenance.js
index 3d3d5e8..078c223 100644
--- a/public/js/maintenance.js
+++ b/public/js/maintenance.js
@@ -43,4 +43,24 @@ function cleanLogs(){
43} 43}
44 44
45// notification après restauration 45// notification après restauration
46// et éventuellement récupérer le message de l'exception d'une autre manière 46document.addEventListener('DOMContentLoaded', function(){
47 const params = new URLSearchParams(window.location.search);
48 // ça pourrait être bien de récupérer le message d'erreur de l'exception d'une autre manière (message dans la variable globale window? c'est faisable??)
49
50 if(typeof window.error_message !== "undefined"){
51 toastNotify(window.error_message);
52 }
53
54 if(params.has('read_backups_dir')){
55 toastNotify("Une erreur s'est produite:<br>" + params.get('read_backups_dir'));
56 }
57
58 if(params.has('database_restauration')){
59 if(params.get('database_restauration') === 'successful'){
60 toastNotify("La base de données a été restaurée avec succès !!");
61 }
62 else{
63 toastNotify("Une erreur s'est produite:<br>" + params.get('database_restauration'));
64 }
65 }
66});
diff --git a/public/js/menu.js b/public/js/menu.js
index c0ec623..41c8709 100644
--- a/public/js/menu.js
+++ b/public/js/menu.js
@@ -45,15 +45,18 @@ function moveOneLevelDown(page_id)
45 }) 45 })
46 .then(response => response.json()) 46 .then(response => response.json())
47 .then(data => { 47 .then(data => {
48 if(data.success) 48 if(data.success){
49 {
50 // affichage 49 // affichage
51 nav_zone.innerHTML = ''; 50 nav_zone.innerHTML = '';
52 nav_zone.insertAdjacentHTML('afterbegin', data.nav); 51 nav_zone.insertAdjacentHTML('afterbegin', data.nav);
53 menu_edit_buttons.innerHTML = ''; 52 menu_edit_buttons.innerHTML = '';
54 menu_edit_buttons.insertAdjacentHTML('afterbegin', data.menu_buttons); 53 menu_edit_buttons.insertAdjacentHTML('afterbegin', data.menu_buttons);
55 } 54 }
56 else { 55 else if(!data.success && data.error == 'new_parent_is_a_link'){
56 toastNotify("Action interdite, une page ne peut avoir pour parent une adresse vers un site web.");
57 console.log("Action interdite, une page ne peut avoir pour parent une adresse vers un site web.");
58 }
59 else{
57 console.error('Échec du déplacement'); 60 console.error('Échec du déplacement');
58 } 61 }
59 }) 62 })
diff --git a/src/controller/MaintenanceController.php b/src/controller/MaintenanceController.php
index f3352d8..3b58fe6 100644
--- a/src/controller/MaintenanceController.php
+++ b/src/controller/MaintenanceController.php
@@ -5,7 +5,6 @@ declare(strict_types=1);
5 5
6use Doctrine\ORM\EntityManager; 6use Doctrine\ORM\EntityManager;
7use App\Entity\log; 7use App\Entity\log;
8use Symfony\Component\Process\Exception\ProcessFailedException;
9use Symfony\Component\HttpFoundation\File\UploadedFile; 8use Symfony\Component\HttpFoundation\File\UploadedFile;
10 9
11class MaintenanceController 10class MaintenanceController
@@ -61,9 +60,8 @@ class MaintenanceController
61 die; 60 die;
62 } 61 }
63 // exeptions lancées dans Backup::mySQLdump 62 // exeptions lancées dans Backup::mySQLdump
64 catch(ProcessFailedException $e){ // pas d'info $e pour le client 63 catch(RuntimeException $e){ // pas d'info $e pour le client7
65 header('Location: ' . new URL(['page' => 'maintenance', 'error' => '500'])); 64 header('Location: ' . new URL(['page' => 'maintenance', 'get_last_dump' => $e->getMessage()]));
66 die;
67 } 65 }
68 die; 66 die;
69 } 67 }
diff --git a/src/controller/MenuAndPathsController.php b/src/controller/MenuAndPathsController.php
index 4d37f3d..799f14b 100644
--- a/src/controller/MenuAndPathsController.php
+++ b/src/controller/MenuAndPathsController.php
@@ -141,7 +141,7 @@ class MenuAndPathsController
141 $page = Model::$menu->findPageById((int)$id); 141 $page = Model::$menu->findPageById((int)$id);
142 142
143 $parent = $page->getParent(); // peut être null 143 $parent = $page->getParent(); // peut être null
144 if($parent == null){ 144 if($parent === null){
145 $parent = Model::$menu; 145 $parent = Model::$menu;
146 } 146 }
147 147
@@ -150,6 +150,12 @@ class MenuAndPathsController
150 if($page->getPosition() > 1){ 150 if($page->getPosition() > 1){
151 foreach($parent->getChildren() as $child){ 151 foreach($parent->getChildren() as $child){
152 if($child->getPosition() === $page->getPosition() - 1){ 152 if($child->getPosition() === $page->getPosition() - 1){
153 // refus si $parent est une adresse, ça va casser le lien, exemple: index.php?page=chemin/http://un_site_web.fr/vers/ici
154 if(str_starts_with($child->getEndOfPath(), 'http')){
155 echo json_encode(['success' => false, 'error' => 'new_parent_is_a_link']);
156 die;
157 }
158
153 $page->setParent($child); 159 $page->setParent($child);
154 break; 160 break;
155 } 161 }
diff --git a/src/controller/UserController.php b/src/controller/UserController.php
index 9746a47..f911d2d 100644
--- a/src/controller/UserController.php
+++ b/src/controller/UserController.php
@@ -92,7 +92,13 @@ class UserController
92 $_SESSION['user']['role'] = $user->getRole(); 92 $_SESSION['user']['role'] = $user->getRole();
93 93
94 EmailService::cleanEmails($entityManager); 94 EmailService::cleanEmails($entityManager);
95 Backup::mySQLdump($entityManager, 'auto'); // créer un nouveau backup 95
96 try{
97 Backup::mySQLdump($entityManager, 'auto'); // créer un nouveau backup
98 }
99 catch(RuntimeException $e){
100 echo '<script>window.error_message = "' . $e->getMessage() . '";</script>';
101 }
96 102
97 $url = new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []); 103 $url = new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []);
98 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : ''; 104 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : '';
diff --git a/src/service/Backup.php b/src/service/Backup.php
index 8a3030f..c886617 100644
--- a/src/service/Backup.php
+++ b/src/service/Backup.php
@@ -74,12 +74,17 @@ class Backup
74 74
75 static public function getBackupList(): array 75 static public function getBackupList(): array
76 { 76 {
77 $files = scandir(Backup::$backup_dir); // affiche un warning si échoue (à cacher en prod)
78 if(!$files){
79 throw new RuntimeException("Le serveur a rencontré une erreur:<br>Accès aux backups impossible faute de permissions.");
80 }
81
77 $backup_array = []; 82 $backup_array = [];
78 foreach(scandir(Backup::$backup_dir) as $file){ 83 foreach($files as $file){
79 if($file[0] === '.'){ 84 if($file[0] === '.'){
80 continue; 85 continue;
81 } 86 }
82 $backup_array[] = $file; 87 $backup_array[] = $file;
83 } 88 }
84 return $backup_array; 89 return $backup_array;
85 } 90 }
@@ -185,6 +190,7 @@ class Backup
185 password=" . Config::$password . "\n 190 password=" . Config::$password . "\n
186 host=" . Config::$db_host . "\n"); 191 host=" . Config::$db_host . "\n");
187 192
193 //$file_name = self::gzipExtract($file_name); // '.gz' ajouté à la fin
188 194
189 $command = new Process([ 195 $command = new Process([
190 $engine, // mariadb ou mysql 196 $engine, // mariadb ou mysql
diff --git a/src/view/MaintenanceBuilder.php b/src/view/MaintenanceBuilder.php
index d9c52b1..c5f53ab 100644
--- a/src/view/MaintenanceBuilder.php
+++ b/src/view/MaintenanceBuilder.php
@@ -11,7 +11,14 @@ class MaintenanceBuilder extends AbstractBuilder
11 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; 11 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
12 12
13 // noter qu'un backup vient d'être créé depuis ViewDirector 13 // noter qu'un backup vient d'être créé depuis ViewDirector
14 $backup_array = Backup::getBackupList(); 14 try{
15 $backup_array = Backup::getBackupList();
16 }
17 // exeptions lancées dans Backup::mySQLdump
18 catch(RuntimeException $e){ // pas d'info $e pour le client
19 $backup_array = [];
20 echo '<script>window.error_message = "' . $e->getMessage() . '";</script>';
21 }
15 $backup_options = ''; 22 $backup_options = '';
16 for($i = count($backup_array) - 1; $i >= 0; $i--){ 23 for($i = count($backup_array) - 1; $i >= 0; $i--){
17 $backup_options .= '<option value="' . $backup_array[$i] . '">' . $backup_array[$i] . '</option>'; 24 $backup_options .= '<option value="' . $backup_array[$i] . '">' . $backup_array[$i] . '</option>';
diff --git a/src/view/MenuBuilder.php b/src/view/MenuBuilder.php
index 85335df..0395dfa 100644
--- a/src/view/MenuBuilder.php
+++ b/src/view/MenuBuilder.php
@@ -13,10 +13,10 @@ class MenuBuilder extends AbstractBuilder
13 //private int $margin_left_multiplier = 29; 13 //private int $margin_left_multiplier = 29;
14 private string $options = ''; 14 private string $options = '';
15 15
16 public function __construct(Node $node, bool $template = true) 16 public function __construct(?Node $node, bool $template = true)
17 { 17 {
18 // dans une ancienne version $node pouvait être null mais je ne sais plus pourquoi 18 // $node peut $etre null parce qu'on ne construit pas de page dans MenuAndPathsController, on ne lit pas la table "node", etc
19 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; 19 $viewFile = $node === null ? self::VIEWS_PATH . 'menu.php' : self::VIEWS_PATH . $node->getName() . '.php';
20 20
21 if(file_exists($viewFile)) 21 if(file_exists($viewFile))
22 { 22 {
diff --git a/src/view/templates/menu.php b/src/view/templates/menu.php
index 1159455..ccfb518 100644
--- a/src/view/templates/menu.php
+++ b/src/view/templates/menu.php
@@ -31,7 +31,7 @@
31 <p><img src="assets/arrow-right.svg"> devenir une branche de l'élément précédent</p> 31 <p><img src="assets/arrow-right.svg"> devenir une branche de l'élément précédent</p>
32 <p><img src="assets/arrow-up.svg"><img src="assets/arrow-down.svg"> déplacer la branche parmi celles de même niveau</p> 32 <p><img src="assets/arrow-up.svg"><img src="assets/arrow-down.svg"> déplacer la branche parmi celles de même niveau</p>
33 <p><input type="checkbox" checked> afficher/cacher</p> 33 <p><input type="checkbox" checked> afficher/cacher</p>
34 <p><img src="assets/edit.svg"> modifier un lien</p> 34 <p><img src="assets/save.svg"> enregistrer une modification</p>
35 <p><img src="assets/delete-bin.svg"> supprimer un lien</p> 35 <p><img src="assets/delete-bin.svg"> supprimer un lien</p>
36 </div> 36 </div>
37 </aside> 37 </aside>