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 }