101 lines
3.2 KiB
PHP
101 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Doctor\Command;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Specialty\Entity\Specialty;
|
|
use App\Specialty\Repository\SpecialtyRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
|
|
/**
|
|
* backfill: پزشکانی که فقط تخصص فرزند دارند (مثلاً «گوارش و کبد» بدون «داخلی»)
|
|
* تمام تخصصهای والد تا ریشهٔ درخت را میگیرند. idempotent؛ با --dry-run فقط گزارش میدهد.
|
|
*
|
|
* php bin/console app:doctors:backfill-specialty-parents --dry-run
|
|
* php bin/console app:doctors:backfill-specialty-parents
|
|
*/
|
|
#[AsCommand(
|
|
name: 'app:doctors:backfill-specialty-parents',
|
|
description: 'Attach every ancestor specialty to doctors that only have the child one (idempotent, supports --dry-run)',
|
|
)]
|
|
class BackfillDoctorSpecialtyParentsCommand extends Command
|
|
{
|
|
public function __construct(
|
|
private readonly EntityManagerInterface $em,
|
|
private readonly SpecialtyRepository $specialtyRepo,
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
protected function configure(): void
|
|
{
|
|
$this->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;
|
|
}
|
|
}
|