get('mb_level'); if (Roles::isSuperAdminEquivalent($level)) { $idx = session()->get('admin_selected_lg_idx'); return $idx !== null && $idx !== '' ? (int) $idx : null; } if ($level === Roles::LEVEL_LOCAL_ADMIN) { $idx = session()->get('mb_lg_idx'); return $idx !== null && $idx !== '' ? (int) $idx : null; } return null; } } if (! function_exists('get_admin_nav_items')) { /** * 관리자 상단 메뉴 항목 (DB menu 테이블, admin 타입, 현재 지자체·mb_level 기준, 평면 배열). * 지자체 미선택(super/본부)이면 빈 배열. 테이블/조회 실패 시에도 빈 배열. * * 하위 메뉴 포함 트리 구조가 필요하면 get_admin_nav_tree() 사용. */ function get_admin_nav_items(): array { try { $lgIdx = admin_effective_lg_idx(); if ($lgIdx === null) { return []; } $typeRow = model(\App\Models\MenuTypeModel::class)->getByCode('admin'); if (! $typeRow) { return []; } $mbLevel = (int) session()->get('mb_level'); return model(\App\Models\MenuModel::class)->getVisibleByLevel((int) $typeRow->mt_idx, $mbLevel, $lgIdx); } catch (\Throwable $e) { return []; } } } if (! function_exists('build_menu_tree')) { /** * menu 평면 배열을 mm_pidx/mm_idx 기준 트리로 변환. * * @param array $items * @return array 루트 노드 배열 */ function build_menu_tree(array $items): array { $map = []; foreach ($items as $item) { $item->children = []; $map[(int) $item->mm_idx] = $item; } $roots = []; foreach ($map as $id => $item) { $pidx = (int) $item->mm_pidx; if ($pidx === 0 || ! isset($map[$pidx])) { $roots[] = $item; } else { $map[$pidx]->children[] = $item; } } return $roots; } } if (! function_exists('flatten_menu_tree')) { /** * 트리 구조의 메뉴를 상위 → 하위 순으로 평면 배열로 풀어낸다. * 관리자 메뉴 목록 화면에서 "부모 바로 아래에 자식"이 나오도록 하기 위한 용도. * * @param array $tree * @return array */ function flatten_menu_tree(array $tree): array { $result = []; $walk = function ($nodes) use (&$result, &$walk) { foreach ($nodes as $node) { $children = $node->children ?? []; // children 속성은 목록에서 사용하지 않으므로 제거 unset($node->children); $result[] = $node; if (! empty($children)) { $walk($children); } } }; $walk($tree); return $result; } } if (! function_exists('get_admin_nav_tree')) { /** * 관리자 상단 메뉴 트리 (admin 타입, 현재 지자체·mb_level 기준). * 1차 메뉴는 mm_pidx=0, 하위 메뉴는 children 속성으로 접근. */ function get_admin_nav_tree(): array { $flat = get_admin_nav_items(); if (empty($flat)) { return []; } return build_menu_tree($flat); } } if (! function_exists('get_site_nav_tree')) { /** * 일반 사이트 상단 메뉴 트리 (site 타입, 현재 회원의 지자체·mb_level 기준). * 1차 메뉴는 mm_pidx=0, 하위 메뉴는 children 속성으로 접근. */ function get_site_nav_tree(): array { try { $lgIdx = session()->get('mb_lg_idx'); // 시민 등 지자체 정보가 세션에 없으면 기본 지자체(1) 기준으로 메뉴를 보여 준다. if ($lgIdx === null || $lgIdx === '') { $lgIdx = 1; } $typeRow = model(\App\Models\MenuTypeModel::class)->getByCode('site'); if (! $typeRow) { return []; } $mbLevel = (int) session()->get('mb_level'); $menuModel = model(\App\Models\MenuModel::class); $flat = $menuModel->getVisibleByLevel((int) $typeRow->mt_idx, $mbLevel, (int) $lgIdx); // 현재 지자체에 site 메뉴가 없으면, 기본 지자체(1)의 메뉴를 한 번 복사한 뒤 다시 시도 if (empty($flat)) { $menuModel->copyDefaultsFromLg((int) $typeRow->mt_idx, 1, (int) $lgIdx); $flat = $menuModel->getVisibleByLevel((int) $typeRow->mt_idx, $mbLevel, (int) $lgIdx); } if (empty($flat)) { return []; } return build_menu_tree($flat); } catch (\Throwable $e) { return []; } } }