diff --git a/application/controllers/OrgRoleController.php b/application/controllers/OrgRoleController.php index dd68f06..ce87407 100644 --- a/application/controllers/OrgRoleController.php +++ b/application/controllers/OrgRoleController.php @@ -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); } } diff --git a/public/js/organigramma.js b/public/js/organigramma.js index 8178e00..770e014 100644 --- a/public/js/organigramma.js +++ b/public/js/organigramma.js @@ -61,10 +61,15 @@ function orgRender() { el('org-stat-vacant').textContent = vacant; stats.style.display = 'flex'; - tree.innerHTML = ORG.tree.map(orgNodeHtml).join(''); + tree.innerHTML = ORG.tree.map(n => orgNodeHtml(n, new Set())).join(''); } -function orgNodeHtml(node) { +function orgNodeHtml(node, seen) { + // Guardia anti-ciclo: se un id ricompare nella catena il render si fermerebbe in loop + // infinito (il "blocco del sito" segnalato). Rompiamo il ciclo invece di ricorrere. + seen = seen || new Set(); + if (!node || seen.has(node.id)) return ''; + seen.add(node.id); const gov = node.is_governance_body; const holder = node.holder_name ? '
👤 ' + esc(node.holder_name) + '
' @@ -72,7 +77,7 @@ function orgNodeHtml(node) { const desc = node.description ? '
' + esc(node.description) + '
' : ''; const govBadge = gov ? 'Governance · Art. 23' : ''; const children = (node.children && node.children.length) - ? '
' + node.children.map(orgNodeHtml).join('') + '
' + ? '
' + node.children.map(c => orgNodeHtml(c, seen)).join('') + '
' : ''; return '' + diff --git a/public/organigramma.html b/public/organigramma.html index 35e3b72..a926c0e 100644 --- a/public/organigramma.html +++ b/public/organigramma.html @@ -157,7 +157,7 @@ - +