115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
// LanguageMiddleware discovers client's language and stores it in context
|
|
// Priority: Query param > Cookie > Accept-Language header > Default language
|
|
func LanguageMiddleware() fiber.Handler {
|
|
langService := langsService.LangSrv
|
|
|
|
return func(c fiber.Ctx) error {
|
|
var langID uint
|
|
|
|
// 1. Check query parameter
|
|
langIDStr := c.Query("lang_id", "")
|
|
if langIDStr != "" {
|
|
if id, err := strconv.ParseUint(langIDStr, 10, 32); err == nil {
|
|
langID = uint(id)
|
|
if langID > 0 {
|
|
lang, err := langService.GetLanguageById(langID)
|
|
if err == nil {
|
|
c.Locals("langID", langID)
|
|
c.Locals("lang", lang)
|
|
return c.Next()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. Check cookie
|
|
cookieLang := c.Cookies("lang_id", "")
|
|
if cookieLang != "" {
|
|
if id, err := strconv.ParseUint(cookieLang, 10, 32); err == nil {
|
|
langID = uint(id)
|
|
if langID > 0 {
|
|
lang, err := langService.GetLanguageById(langID)
|
|
if err == nil {
|
|
c.Locals("langID", langID)
|
|
c.Locals("lang", lang)
|
|
return c.Next()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 3. Check Accept-Language header
|
|
acceptLang := c.Get("Accept-Language", "")
|
|
if acceptLang != "" {
|
|
// Parse the Accept-Language header (e.g., "en-US,en;q=0.9,pl;q=0.8")
|
|
isoCode := parseAcceptLanguage(acceptLang)
|
|
if isoCode != "" {
|
|
lang, err := langService.GetLanguageByISOCode(isoCode)
|
|
if err == nil && lang != nil {
|
|
langID = uint(lang.ID)
|
|
c.Locals("langID", langID)
|
|
c.Locals("lang", lang)
|
|
return c.Next()
|
|
}
|
|
}
|
|
}
|
|
|
|
// 4. Fall back to default language
|
|
defaultLang, err := langService.GetDefaultLanguage()
|
|
if err == nil && defaultLang != nil {
|
|
langID = uint(defaultLang.ID)
|
|
c.Locals("langID", langID)
|
|
c.Locals("lang", defaultLang)
|
|
}
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// parseAcceptLanguage extracts the primary language ISO code from Accept-Language header
|
|
func parseAcceptLanguage(header string) string {
|
|
// Split by comma
|
|
parts := strings.Split(header, ",")
|
|
if len(parts) == 0 {
|
|
return ""
|
|
}
|
|
|
|
// Get the first part (highest priority)
|
|
first := strings.TrimSpace(parts[0])
|
|
if first == "" {
|
|
return ""
|
|
}
|
|
|
|
// Remove any quality value (e.g., ";q=0.9")
|
|
if idx := strings.Index(first, ";"); idx != -1 {
|
|
first = strings.TrimSpace(first[:idx])
|
|
}
|
|
|
|
// Handle cases like "en-US" or "en"
|
|
// Return the primary language code (first part before dash)
|
|
if idx := strings.Index(first, "-"); idx != -1 {
|
|
return strings.ToLower(first[:idx])
|
|
}
|
|
|
|
return strings.ToLower(first)
|
|
}
|
|
|
|
// GetLanguageID extracts language ID from context
|
|
func GetLanguageID(c fiber.Ctx) uint {
|
|
langID, ok := c.Locals("langID").(uint)
|
|
if !ok {
|
|
return 0
|
|
}
|
|
return langID
|
|
}
|