fix:사이드바 메뉴 prefix 매칭 시 더 구체적인 메뉴 우선 적용

/esign/templates/5/fields 접속 시 /esign, /esign/templates 둘 다
활성화되던 문제 수정. 더 구체적인 prefix 메뉴가 있으면 덜 구체적인
메뉴는 비활성화.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-13 07:09:14 +09:00
parent f83a62b479
commit 631287e75e

View File

@@ -172,10 +172,11 @@ public function isMenuActive(Menu $menu): bool
return true;
}
// prefix 매칭: 다른 메뉴가 현재 URL에 정확히 매칭되면 prefix 매칭 비활성화
// (예: /esign/create 접속 시, /esign 메뉴가 prefix로 잘못 활성화되는 것 방지)
// prefix 매칭: 더 구체적인 메뉴가 있으면 덜 구체적인 prefix 매칭 비활성화
// (예: /esign/templates/5/fields 접속 시, /esign/templates 메뉴만 활성화, /esign 메뉴는 비활성)
if (str_starts_with($currentPath, $menu->url.'/')) {
return !self::hasExactMenuMatch($currentPath);
return !self::hasExactMenuMatch($currentPath)
&& !self::hasMoreSpecificPrefixMenu($currentPath, $menu->url);
}
return false;
@@ -261,6 +262,35 @@ private static function hasExactMenuMatch(string $currentPath): bool
return self::$exactMatchCache;
}
/**
* 현재 경로에 대해 더 구체적인 prefix를 가진 메뉴가 있는지 확인
* (예: 현재 메뉴 URL이 /esign이고, /esign/templates 메뉴도 있으면 true)
*/
private static array $prefixMenuCache = [];
private static function hasMoreSpecificPrefixMenu(string $currentPath, string $menuUrl): bool
{
$cacheKey = $currentPath . '|' . $menuUrl;
if (isset(self::$prefixMenuCache[$cacheKey])) {
return self::$prefixMenuCache[$cacheKey];
}
$tenantId = auth()->user()?->tenant_id ?? 1;
// 현재 경로의 prefix이면서 이 메뉴 URL보다 긴 URL을 가진 활성 메뉴가 있는지 확인
$result = Menu::withoutGlobalScopes()
->where('tenant_id', $tenantId)
->where('is_active', true)
->whereNotNull('url')
->where('url', '!=', $menuUrl)
->whereRaw('LENGTH(url) > ?', [strlen($menuUrl)])
->whereRaw("? LIKE CONCAT(url, '/%')", [$currentPath])
->exists();
self::$prefixMenuCache[$cacheKey] = $result;
return $result;
}
/**
* 메뉴 또는 자식 메뉴가 활성 상태인지 확인
*/