diff options
| author | polo <ordipolo@gmx.fr> | 2026-05-12 00:59:34 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2026-05-12 00:59:34 +0200 |
| commit | 007b193177fbe5ffd574940b9a0ae4ec418171a5 (patch) | |
| tree | 3889002ff4a790137977d02f4cb6689d0611abdb | |
| parent | 80de6834a11734c6d3e047635b63ec93f2f68345 (diff) | |
| download | cms-007b193177fbe5ffd574940b9a0ae4ec418171a5.tar.gz cms-007b193177fbe5ffd574940b9a0ae4ec418171a5.tar.bz2 cms-007b193177fbe5ffd574940b9a0ae4ec418171a5.zip | |
on garde le premier before-restore du jour, cleanBackups avec tri et priorités, oubli dans mysqldump.php
| -rw-r--r-- | bin/mysqldump.php | 2 | ||||
| -rw-r--r-- | public/js/maintenance.js | 4 | ||||
| -rw-r--r-- | src/controller/MaintenanceController.php | 4 | ||||
| -rw-r--r-- | src/service/Backup.php | 75 |
4 files changed, 73 insertions, 12 deletions
diff --git a/bin/mysqldump.php b/bin/mysqldump.php index 4356a81..b7ae3ef 100644 --- a/bin/mysqldump.php +++ b/bin/mysqldump.php | |||
| @@ -9,5 +9,5 @@ require "../vendor/autoload.php"; | |||
| 9 | Config::load('../config/config.ini'); | 9 | Config::load('../config/config.ini'); |
| 10 | require '../src/model/doctrine-bootstrap.php'; | 10 | require '../src/model/doctrine-bootstrap.php'; |
| 11 | 11 | ||
| 12 | $file_name = Backup::mySQLdump($entityManager); // créer un nouveau backup | 12 | $file_name = Backup::mySQLdump($entityManager, 'console'); // créer un nouveau backup |
| 13 | echo realpath($file_name) . "\n"; \ No newline at end of file | 13 | echo realpath($file_name) . "\n"; \ No newline at end of file |
diff --git a/public/js/maintenance.js b/public/js/maintenance.js index 87f4aec..3d3d5e8 100644 --- a/public/js/maintenance.js +++ b/public/js/maintenance.js | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | // js/maintenance.js | ||
| 2 | |||
| 1 | function displayLogs(){ | 3 | function displayLogs(){ |
| 2 | const log_table = getElementOrThrow('log_table'); | 4 | const log_table = getElementOrThrow('log_table'); |
| 3 | 5 | ||
| @@ -41,4 +43,4 @@ function cleanLogs(){ | |||
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | // notification après restauration | 45 | // notification après restauration |
| 44 | 46 | // et éventuellement récupérer le message de l'exception d'une autre manière | |
diff --git a/src/controller/MaintenanceController.php b/src/controller/MaintenanceController.php index c62b21b..83304de 100644 --- a/src/controller/MaintenanceController.php +++ b/src/controller/MaintenanceController.php | |||
| @@ -81,7 +81,7 @@ class MaintenanceController | |||
| 81 | static public function downloadSQL(EntityManager $entityManager, UploadedFile $uploaded_file): void | 81 | static public function downloadSQL(EntityManager $entityManager, UploadedFile $uploaded_file): void |
| 82 | { | 82 | { |
| 83 | if(pathinfo($uploaded_file->getClientOriginalName())['extension'] !== 'sql'){ | 83 | if(pathinfo($uploaded_file->getClientOriginalName())['extension'] !== 'sql'){ |
| 84 | throw new Exception("charger un fichier au format SQL"); | 84 | throw new Exception("Charger un fichier au format SQL"); |
| 85 | } | 85 | } |
| 86 | //echo $uploaded_file->getSize(); // à garder de côté au cas où | 86 | //echo $uploaded_file->getSize(); // à garder de côté au cas où |
| 87 | 87 | ||
| @@ -89,7 +89,7 @@ class MaintenanceController | |||
| 89 | 89 | ||
| 90 | try{ | 90 | try{ |
| 91 | // enregistrer le fichier | 91 | // enregistrer le fichier |
| 92 | var_dump($uploaded_file->move(Backup::$backup_dir, $server_place)); | 92 | $uploaded_file->move(Backup::$backup_dir, $server_place); |
| 93 | 93 | ||
| 94 | // s'en servir | 94 | // s'en servir |
| 95 | Backup::restoreDatabase($entityManager, $server_place); | 95 | Backup::restoreDatabase($entityManager, $server_place); |
diff --git a/src/service/Backup.php b/src/service/Backup.php index 63368b5..1b44351 100644 --- a/src/service/Backup.php +++ b/src/service/Backup.php | |||
| @@ -9,7 +9,7 @@ use Symfony\Component\Process\Process; // protection injection dans le shell | |||
| 9 | class Backup | 9 | class Backup |
| 10 | { | 10 | { |
| 11 | static public string $backup_dir = '../var/backups'; | 11 | static public string $backup_dir = '../var/backups'; |
| 12 | static private int $amount_to_keep = 30; | 12 | static private int $amount_to_keep = 20; |
| 13 | 13 | ||
| 14 | static public function mySQLdump(EntityManager $entityManager, string $type): string | 14 | static public function mySQLdump(EntityManager $entityManager, string $type): string |
| 15 | { | 15 | { |
| @@ -81,19 +81,78 @@ class Backup | |||
| 81 | return $backup_list[count($backup_list) - 1]; | 81 | return $backup_list[count($backup_list) - 1]; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static public function cleanBackups(): void { | 84 | static public function cleanBackups(): void |
| 85 | { | ||
| 85 | $files = glob(self::$backup_dir . '/*.sql'); | 86 | $files = glob(self::$backup_dir . '/*.sql'); |
| 86 | usort($files, fn($a, $b) => filemtime($b) <=> filemtime($a)); // filemtime = date de dernière modification | 87 | //usort($files, fn($a, $b) => filemtime($b) <=> filemtime($a)); // filemtime = date de dernière modification |
| 87 | $files_to_delete = array_slice($files, self::$amount_to_keep); | 88 | arsort($files); |
| 88 | foreach($files_to_delete as $file){ | 89 | |
| 89 | unlink($file); | 90 | // tri par nom de BDD puis par date |
| 91 | $sorted_files = []; | ||
| 92 | $list_by_database = []; // pour le nettoyage 2 | ||
| 93 | foreach($files as $file){ | ||
| 94 | $exploded = explode('_', basename($file)); | ||
| 95 | $sorted_files[$exploded[0]][$exploded[1]][] = $file; | ||
| 96 | $list_by_database[$exploded[0]][] = $file; | ||
| 97 | } | ||
| 98 | |||
| 99 | $today = new DateTime()->format('Y-m-d'); | ||
| 100 | foreach($sorted_files as $db_name => $from_one_database){ | ||
| 101 | // on garde une "quantité à garder" par BDD | ||
| 102 | if(count($from_one_database) > self::$amount_to_keep){ | ||
| 103 | // nettoyage 1 | ||
| 104 | foreach($from_one_database as $date => $with_same_date){ | ||
| 105 | // pas touche à aujourd'hui | ||
| 106 | if($date != $today){ | ||
| 107 | self::cleanBackupsByPriority($with_same_date); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | // nettoyage 2 | ||
| 111 | $files_to_delete = array_slice($list_by_database[$db_name], self::$amount_to_keep); | ||
| 112 | foreach($files_to_delete as $file){ | ||
| 113 | unlink($file); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | // conserver un seul backup par jour choisi dans cet ordre de préférence: console => before-restore => download => auto | ||
| 120 | // cet ordre correspond à: volonté de l'utilisateur => état du jour avant changement => volonté de changement => automatique sans contrôle | ||
| 121 | static private function cleanBackupsByPriority(array $files): void | ||
| 122 | { | ||
| 123 | $priorities = [ | ||
| 124 | 'console' => 1, | ||
| 125 | 'before-restore' => 2, | ||
| 126 | 'uploaded' => 3, | ||
| 127 | 'auto' => 4, | ||
| 128 | ]; | ||
| 129 | $best_priority = PHP_INT_MAX; | ||
| 130 | |||
| 131 | // recherche du fichier à conserver | ||
| 132 | $to_keep = null; | ||
| 133 | foreach($files as $file){ | ||
| 134 | foreach($priorities as $keyword => $priority){ | ||
| 135 | if(str_contains(basename($file), $keyword) && $priority < $best_priority){ | ||
| 136 | $best_priority = $priority; | ||
| 137 | $to_keep = $file; | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | // suppression des autres | ||
| 143 | foreach($files as $file){ | ||
| 144 | if($file !== $to_keep){ | ||
| 145 | unlink($file); | ||
| 146 | } | ||
| 90 | } | 147 | } |
| 91 | } | 148 | } |
| 92 | 149 | ||
| 93 | static public function restoreDatabase(EntityManager $entityManager, string $file_name): void | 150 | static public function restoreDatabase(EntityManager $entityManager, string $file_name): void |
| 94 | { | 151 | { |
| 95 | // backup de sécurité | 152 | // création d'un backup de sécurité non écrasable |
| 96 | Backup::mySQLdump($entityManager, 'before-restore'); | 153 | if(!file_exists(self::$backup_dir . '/' . Config::$database . '_' . new DateTime()->format('Y-m-d') . '_before-restore.sql')){ |
| 154 | Backup::mySQLdump($entityManager, 'before-restore'); | ||
| 155 | } | ||
| 97 | 156 | ||
| 98 | $version = $entityManager->getConnection()->fetchOne('SELECT VERSION()'); | 157 | $version = $entityManager->getConnection()->fetchOne('SELECT VERSION()'); |
| 99 | $engine = stripos($version, 'mariadb') !== false ? 'mariadb' : 'mysql'; | 158 | $engine = stripos($version, 'mariadb') !== false ? 'mariadb' : 'mysql'; |
