attributes->has(self::CACHE_KEY)) { return $request->attributes->get(self::CACHE_KEY); } $role = Role::where('identifier', 'guest') ->with('permissions') ->first(); $request->attributes->set(self::CACHE_KEY, $role); return $role; } /** * guest 역할이 특정 권한을 보유하는지 판정합니다. * * 적재해 둔 권한 컬렉션에서 판정하므로 판정마다 쿼리가 나가지 않습니다. * * @param string $identifier 권한 식별자 * @param PermissionType|null $type 권한 타입 (null 이면 타입 무관) * @return bool 보유 여부 */ public static function hasPermission(string $identifier, ?PermissionType $type = null): bool { $role = self::resolve(); if (! $role) { return false; } foreach ($role->permissions as $permission) { if ($permission->identifier !== $identifier) { continue; } if ($type === null || self::permissionType($permission) === $type) { return true; } } return false; } /** * 캐시를 비웁니다. * * 권한 재시드(코어 업데이트 / 확장 설치) 직후처럼 같은 요청 안에서 권한 구성이 * 바뀌는 경우에 호출합니다. */ public static function flush(): void { request()->attributes->remove(self::CACHE_KEY); } /** * 권한의 타입을 Enum 으로 정규화합니다. * * @param Permission $permission 권한 모델 * @return PermissionType|null 정규화된 타입 (해석 불가 시 null) */ private static function permissionType($permission): ?PermissionType { $type = $permission->type; if ($type instanceof PermissionType) { return $type; } return $type === null ? null : PermissionType::tryFrom((string) $type); } }