addOption('dry-run', null, InputOption::VALUE_NONE, 'Report only, change nothing'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $dryRun = (bool) $input->getOption('dry-run'); /** @var Doctor[] $doctors */ $doctors = $this->em->getRepository(Doctor::class)->findAll(); $touched = 0; $added = 0; foreach ($doctors as $doctor) { $current = array_map( static fn (Specialty $s) => $s->getId(), $doctor->getSpecialties()->toArray() ); if ($current === []) { continue; } $missing = array_diff($this->specialtyRepo->expandWithAncestors($current), $current); if ($missing === []) { continue; } $io->text(sprintf( '%s doctor #%d — adding specialty %s', $dryRun ? '[dry-run]' : '[update]', $doctor->getId(), implode(', ', $missing) )); if (!$dryRun) { foreach ($missing as $id) { $s = $this->specialtyRepo->find($id); if ($s !== null) { $doctor->getSpecialties()->add($s); } } } $touched++; $added += count($missing); } if (!$dryRun && $touched > 0) { $this->em->flush(); } $io->success(sprintf( '%d doctor(s) %s, %d specialty link(s) added (of %d scanned)', $touched, $dryRun ? 'would be updated' : 'updated', $added, count($doctors) )); return Command::SUCCESS; } }