feat: implement specialty hierarchy handling in doctor and representation APIs, add backfill command and tests
This commit is contained in:
@@ -9,6 +9,9 @@ use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
class SpecialtyRepository extends ServiceEntityRepository
|
||||
{
|
||||
/** @var array<int,?int>|null */
|
||||
private ?array $parentMap = null;
|
||||
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Specialty::class);
|
||||
@@ -62,6 +65,52 @@ class SpecialtyRepository extends ServiceEntityRepository
|
||||
return $this->findOneBy(['slug' => $slug]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialty ids plus every ancestor up to the root, unique and sorted.
|
||||
* Unknown ids are dropped; a cyclic parent chain stops at the repeated id.
|
||||
*
|
||||
* @param int[] $ids
|
||||
* @return int[]
|
||||
*/
|
||||
public function expandWithAncestors(array $ids): array
|
||||
{
|
||||
$map = $this->parentMap();
|
||||
$out = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$cur = (int) $id;
|
||||
$seen = [];
|
||||
while (array_key_exists($cur, $map) && !isset($seen[$cur])) {
|
||||
$seen[$cur] = true;
|
||||
$out[$cur] = true;
|
||||
$cur = $map[$cur] ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
$out = array_keys($out);
|
||||
sort($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/** @return array<int,?int> id => parentId for every specialty */
|
||||
private function parentMap(): array
|
||||
{
|
||||
if ($this->parentMap === null) {
|
||||
$rows = $this->createQueryBuilder('s')
|
||||
->select('s.id AS id', 'IDENTITY(s.parent) AS parent')
|
||||
->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$this->parentMap = [];
|
||||
foreach ($rows as $row) {
|
||||
$this->parentMap[(int) $row['id']] = $row['parent'] !== null ? (int) $row['parent'] : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->parentMap;
|
||||
}
|
||||
|
||||
public function save(Specialty $specialty, bool $flush = true): void
|
||||
{
|
||||
$this->getEntityManager()->persist($specialty);
|
||||
|
||||
Reference in New Issue
Block a user