Files
b2b/app/delivery/middleware/language.go
2026-03-31 16:56:05 +02:00

105 lines
2.7 KiB
Go

package middleware
import (
"strconv"
"strings"
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"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 {
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
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 {
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
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(constdata.USER_LOCALE, returnNewLocale(langID))
return c.Next()
}
}
}
// 4. Fall back to default language
defaultLang, err := langService.GetDefaultLanguage()
if err == nil && defaultLang != nil {
langID = uint(defaultLang.ID)
c.Locals(constdata.USER_LOCALE, returnNewLocale(langID))
}
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)
}
func returnNewLocale(lang_id uint) *model.UserLocale {
newLocale := model.UserLocale{}
newLocale.OriginalUser = &model.Customer{}
newLocale.OriginalUser.LangID = lang_id
return &newLocale
}