[FIX] Organigramma: guardia anti-ciclo (client+server) — "Nuovo Ruolo" bloccava il sito

Segnalazione Simon: in Struttura interna/Organigramma il clic su "Nuovo Ruolo"
blocca l'intero sito. Causa: né il tree builder server (OrgRoleController::buildTree,
$attach) né il render client (organigramma.js orgNodeHtml) avevano una guardia
anti-ciclo su parent_role_id → con una gerarchia ciclica la ricorsione va in loop
infinito (hang del backend / freeze del render).
- organigramma.js orgNodeHtml(node, seen): salta gli id già visti (rompe il ciclo);
  orgRender passa un Set condiviso. Live via bind-mount (buster 20260806).
- OrgRoleController::buildTree: $attach porta la catena antenati e non ridiscende su
  un id già visto. ⚠️ Richiede reload php-fpm host (opcache) per andare live.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-08-25 18:00:08 +02:00
co-authored by Claude Opus 4.8
parent 0bf17db50a
commit bfda75b292
3 changed files with 24 additions and 8 deletions
+15 -4
View File
@@ -316,11 +316,22 @@ class OrgRoleController extends BaseController
$roots[] = $r;
}
}
$attach = function (array $node) use (&$attach, $childrenByParent) {
$kids = $childrenByParent[(int) $node['id']] ?? [];
$node['children'] = array_map($attach, $kids);
// Guardia anti-ciclo: se parent_role_id formasse un ciclo (dato legacy/corrotto),
// la ricorsione andrebbe in loop infinito → hang del backend e "blocco" della pagina.
// Portiamo la catena di antenati e non ridiscendiamo su un id già visto.
$attach = function (array $node, array $ancestry) use (&$attach, $childrenByParent) {
$id = (int) $node['id'];
$ancestry[$id] = true;
$children = [];
foreach ($childrenByParent[$id] ?? [] as $kid) {
if (isset($ancestry[(int) $kid['id']])) {
continue; // ciclo: interrompi questo ramo invece di ricorrere all'infinito
}
$children[] = $attach($kid, $ancestry);
}
$node['children'] = $children;
return $node;
};
return array_map($attach, $roots);
return array_map(static fn(array $r) => $attach($r, []), $roots);
}
}