addOption('dry-run', null, InputOption::VALUE_NONE, 'Simule la suppression sans rien effacer') ->setHelp('Supprime les doublons de Stats (même code INSEE), en gardant le plus ancien. Utilisez --dry-run pour simuler.'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $dryRun = $input->getOption('dry-run'); $repo = $this->entityManager->getRepository(Stats::class); $allStats = $repo->findAll(); $io->title('Recherche des doublons Stats par code INSEE'); // Regrouper par code INSEE $statsByZone = []; foreach ($allStats as $stat) { $zone = $stat->getZone(); if (!$zone) continue; $statsByZone[$zone][] = $stat; } $toDelete = []; $toKeep = []; foreach ($statsByZone as $zone => $statsList) { if (count($statsList) > 1) { // Trier par date_created (le plus ancien d'abord), puis par id si date absente usort($statsList, function($a, $b) { $da = $a->getDateCreated(); $db = $b->getDateCreated(); if ($da && $db) { return $da <=> $db; } elseif ($da) { return -1; } elseif ($db) { return 1; } else { return $a->getId() <=> $b->getId(); } }); // Garder le premier, supprimer les autres $toKeep[$zone] = $statsList[0]; $toDelete[$zone] = array_slice($statsList, 1); } } $totalToDelete = array_sum(array_map('count', $toDelete)); if ($totalToDelete === 0) { $io->success('Aucun doublon trouvé.'); return Command::SUCCESS; } $io->section('Résumé des actions par code INSEE :'); foreach ($toDelete as $zone => $statsList) { $io->writeln("Zone INSEE : $zone"); $statKept = $toKeep[$zone]; $io->writeln(sprintf(" Gardé : [ID %d] %s | Créé: %s", $statKept->getId(), $statKept->getName(), $statKept->getDateCreated() ? $statKept->getDateCreated()->format('Y-m-d H:i:s') : 'N/A' )); foreach ($statsList as $stat) { $io->writeln(sprintf(" Supprimé: [ID %d] %s | Créé: %s", $stat->getId(), $stat->getName(), $stat->getDateCreated() ? $stat->getDateCreated()->format('Y-m-d H:i:s') : 'N/A' )); } } $io->warning($totalToDelete . ' objet(s) Stats seraient supprimés.'); if ($dryRun) { $io->note('Mode dry-run : aucune suppression effectuée.'); return Command::SUCCESS; } foreach ($toDelete as $statsList) { foreach ($statsList as $stat) { $this->entityManager->remove($stat); } } $this->entityManager->flush(); $io->success($totalToDelete . ' doublon(s) supprimé(s) !'); return Command::SUCCESS; } }