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 = []; 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 $toDelete = array_merge($toDelete, array_slice($statsList, 1)); } } if (empty($toDelete)) { $io->success('Aucun doublon trouvé.'); return Command::SUCCESS; } $io->warning(count($toDelete) . ' objet(s) Stats seraient supprimés.'); foreach ($toDelete as $stat) { $io->text(sprintf('Zone: %s | ID: %d | Nom: %s | Créé: %s', $stat->getZone(), $stat->getId(), $stat->getName(), $stat->getDateCreated() ? $stat->getDateCreated()->format('Y-m-d H:i:s') : 'N/A' )); } if ($dryRun) { $io->note('Mode dry-run : aucune suppression effectuée.'); return Command::SUCCESS; } foreach ($toDelete as $stat) { $this->entityManager->remove($stat); } $this->entityManager->flush(); $io->success(count($toDelete) . ' doublon(s) supprimé(s) !'); return Command::SUCCESS; } }