66 lines
2.3 KiB
PHP
66 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Doctor\Service\Repair;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Doctor\Service\SourceProfileId;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
|
|
/**
|
|
* پرکردن `source_profile_id` رکوردهای موجود از روی `source_ref` — پیشنیازِ یونیکایندکس
|
|
* `(source, source_profile_id)`. بدون این، رکوردهای قدیمی `source_profile_id=NULL` میمانند
|
|
* و dedup مبتنی بر profile id فقط برای ایمپورتهای جدید کار میکند.
|
|
*/
|
|
final class BackfillSourceProfileIdStep implements DoctorRepairStep
|
|
{
|
|
public function __construct(private readonly EntityManagerInterface $em)
|
|
{
|
|
}
|
|
|
|
public function name(): string
|
|
{
|
|
return 'source-profile-id';
|
|
}
|
|
|
|
public function description(): string
|
|
{
|
|
return 'پرکردن source_profile_id از روی source_ref برای رکوردهای موجود';
|
|
}
|
|
|
|
public function run(RepairOptions $options, SymfonyStyle $io): RepairResult
|
|
{
|
|
$qb = $this->em->getRepository(Doctor::class)->createQueryBuilder('d')
|
|
->where('d.sourceRef IS NOT NULL')
|
|
->andWhere('d.sourceProfileId IS NULL');
|
|
if (!$options->allSources) {
|
|
$qb->andWhere('d.source = :src')->setParameter('src', 'irimc');
|
|
}
|
|
/** @var Doctor[] $doctors */
|
|
$doctors = $qb->getQuery()->getResult();
|
|
|
|
$changed = 0;
|
|
$skipped = 0;
|
|
foreach ($doctors as $doctor) {
|
|
$id = SourceProfileId::fromRef($doctor->getSourceRef());
|
|
if ($id === null) {
|
|
// source_ref قالب شناسهدار ندارد — روی همان کد fallback میشود، تغییری نده.
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
$io->text(sprintf(' #%d %s → %s', $doctor->getId(), $doctor->getName(), $id));
|
|
if (!$options->dryRun) {
|
|
$doctor->setSourceProfileId($id);
|
|
}
|
|
$changed++;
|
|
}
|
|
|
|
return new RepairResult(
|
|
scanned: count($doctors),
|
|
changed: $changed,
|
|
skipped: $skipped,
|
|
note: $skipped > 0 ? "$skipped رکورد بدون شناسهٔ قابل استخراج" : null,
|
|
);
|
|
}
|
|
}
|