diff options
| author | polo <ordipolo@gmx.fr> | 2026-05-19 00:19:23 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2026-05-19 00:19:23 +0200 |
| commit | ac78568e1c1a91564eb6bd35c03d9a8a781bc53d (patch) | |
| tree | 11deab2f8b82c30110faa4329be7c14f2ba394c1 | |
| parent | e79931432e63a86c5b7ced8a41186a24239794fe (diff) | |
| download | cms-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.json | 12 | ||||
| -rw-r--r-- | public/js/maintenance.js | 22 | ||||
| -rw-r--r-- | public/js/menu.js | 9 | ||||
| -rw-r--r-- | src/controller/MaintenanceController.php | 6 | ||||
| -rw-r--r-- | src/controller/MenuAndPathsController.php | 8 | ||||
| -rw-r--r-- | src/controller/UserController.php | 8 | ||||
| -rw-r--r-- | src/service/Backup.php | 16 | ||||
| -rw-r--r-- | src/view/MaintenanceBuilder.php | 9 | ||||
| -rw-r--r-- | src/view/MenuBuilder.php | 6 | ||||
| -rw-r--r-- | src/view/templates/menu.php | 2 |
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 | 46 | document.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 | ||
| 6 | use Doctrine\ORM\EntityManager; | 6 | use Doctrine\ORM\EntityManager; |
| 7 | use App\Entity\log; | 7 | use App\Entity\log; |
| 8 | use Symfony\Component\Process\Exception\ProcessFailedException; | ||
| 9 | use Symfony\Component\HttpFoundation\File\UploadedFile; | 8 | use Symfony\Component\HttpFoundation\File\UploadedFile; |
| 10 | 9 | ||
| 11 | class MaintenanceController | 10 | class 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> |
