public override async Task Invoke(IOwinContext context) { if (!context.Request.Path.StartsWithSegments(new PathString("/admin")) && !context.Request.Path.StartsWithSegments(new PathString("/areas/admin")) && !context.Request.Path.StartsWithSegments(new PathString("/api")) && !context.Request.Path.StartsWithSegments(new PathString("/favicon.ico")) ) { var customerService = _customerServce; var commerceService = _commerceServce; var ctx = SiteContext.Current; ctx.LoginProviders = GetExternalLoginProviders(context).ToArray(); // Need to load language for all files, since translations are used within css and js // the order of execution is very important when initializing context // 1st: initialize some sort of context, especially get a list of all shops first // other methods will rely on that to be performance efficient // 2nd: find current shop from url, which context with shops will be used for ctx.Shops = await commerceService.GetShopsAsync(); // Get current language var language = this.GetLanguage(context).ToSpecificLangCode(); ctx.Language = language; var shop = this.GetStore(context, language); if (shop == null) { await RenderHtmlContents(context, "nostore"); return; } if (await RenderGettingStarted(context)) { return; } var currency = GetStoreCurrency(context, shop); shop.Currency = currency; ctx.Shop = shop; ctx.Themes = await commerceService.GetThemesAsync(SiteContext.Current); if (ctx.Themes == null || !ctx.Themes.Any()) { await RenderHtmlContents(context, "notheme"); return; } // if language is not set, set it to default shop language if (String.IsNullOrEmpty(ctx.Language)) { language = shop.DefaultLanguage; if (String.IsNullOrEmpty(language)) { throw new HttpException(404, "Store language not found"); } CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(language); ctx.Language = language; } if (!this.IsResourceFile()) // only load settings for resource files, no need for other contents { // save info to the cookies context.Response.Cookies.Append( StoreCookie, shop.StoreId, new CookieOptions { Expires = DateTime.UtcNow.AddDays(30) }); context.Response.Cookies.Append( LanguageCookie, ctx.Language, new CookieOptions { Expires = DateTime.UtcNow.AddDays(30) }); context.Response.Cookies.Append( CurrencyCookie, shop.Currency, new CookieOptions { Expires = DateTime.UtcNow.AddDays(30) }); if (context.Authentication.User != null && context.Authentication.User.Identity.IsAuthenticated) { ctx.Customer = await customerService.GetCustomerAsync(context.Authentication.User.Identity.Name, shop.StoreId); if (ctx.Customer == null) { context.Authentication.SignOut(); } else { ctx.CustomerId = ctx.Customer.Id; } } if (ctx.Customer == null) { var cookie = context.Request.Cookies[AnonymousCookie]; if (string.IsNullOrEmpty(cookie)) { cookie = Guid.NewGuid().ToString(); var cookieOptions = new CookieOptions { Expires = DateTime.UtcNow.AddDays(30) }; context.Response.Cookies.Append(AnonymousCookie, cookie, cookieOptions); } ctx.CustomerId = cookie; } // TODO: detect if shop exists, user has access // TODO: store anonymous customer id in cookie and update and merge cart once customer is logged in ctx.Linklists = await commerceService.GetListsAsync(SiteContext.Current); ctx.PageTitle = ctx.Shop.Name; ctx.Collections = await commerceService.GetCollectionsAsync(SiteContext.Current); ctx.Pages = new PageCollection(); ctx.Forms = commerceService.GetForms(); var cart = await commerceService.GetCartAsync(SiteContext.Current.StoreId, SiteContext.Current.CustomerId); if (cart == null) { cart = new Cart(SiteContext.Current.StoreId, SiteContext.Current.CustomerId, SiteContext.Current.Shop.Currency, SiteContext.Current.Language); } ctx.Cart = cart; if (ctx.Shop.QuotesEnabled) { ctx.ActualQuoteRequest = await _quoteService.GetCurrentQuoteRequestAsync(SiteContext.Current.StoreId, SiteContext.Current.CustomerId); if (ctx.ActualQuoteRequest == null) { ctx.ActualQuoteRequest = new QuoteRequest(SiteContext.Current.StoreId, SiteContext.Current.CustomerId); ctx.ActualQuoteRequest.Currency = ctx.Shop.Currency; ctx.ActualQuoteRequest.Tag = "actual"; } if (ctx.Customer != null) { ctx.ActualQuoteRequest.CustomerName = ctx.Customer.Name; } } if (context.Authentication.User.Identity.IsAuthenticated) { var anonymousCookie = context.Request.Cookies[AnonymousCookie]; if (anonymousCookie != null) { var anonymousCart = await commerceService.GetCartAsync(ctx.StoreId, anonymousCookie); if (anonymousCart != null) { ctx.Cart.MergeCartWith(anonymousCart); if (ctx.Cart.IsTransient) { await commerceService.CreateCartAsync(ctx.Cart); } else { await commerceService.SaveChangesAsync(ctx.Cart); } await commerceService.DeleteCartAsync(anonymousCart.Key); } if (ctx.Shop.QuotesEnabled) { var anonymousQuote = await _quoteService.GetCurrentQuoteRequestAsync(ctx.StoreId, anonymousCookie); if (anonymousQuote != null) { ctx.ActualQuoteRequest.MergeQuoteWith(anonymousQuote); await _quoteService.UpdateQuoteRequestAsync(ctx.ActualQuoteRequest); await _quoteService.DeleteAsync(anonymousQuote.Id); } } } context.Response.Cookies.Delete(AnonymousCookie); } ctx.PriceLists = await commerceService.GetPriceListsAsync(ctx.Shop.Catalog, shop.Currency, new TagQuery()); ctx.Theme = commerceService.GetTheme(SiteContext.Current, this.ResolveTheme(shop, context)); // update theme files await commerceService.UpdateThemeCacheAsync(SiteContext.Current); ctx.Blogs = commerceService.GetBlogs(SiteContext.Current); } else { ctx.Theme = commerceService.GetTheme(SiteContext.Current, this.ResolveTheme(shop, context)); } ctx.Settings = commerceService.GetSettings( ctx.Theme.ToString(), context.Request.Path.HasValue && context.Request.Path.Value.Contains(".scss") ? "''" : null); ctx.CountryOptionTags = commerceService.GetCountryTags(); if (ctx.Shop.Currency.Equals("GBP", StringComparison.OrdinalIgnoreCase) || ctx.Shop.Currency.Equals("USD", StringComparison.OrdinalIgnoreCase)) { ctx.Shop.MoneyFormat = commerceService.CurrencyDictionary[ctx.Shop.Currency] + "{{ amount }}"; } else { ctx.Shop.MoneyFormat = "{{ amount }} " + commerceService.CurrencyDictionary[ctx.Shop.Currency]; } var gaTrackingId = ConfigurationManager.AppSettings["GoogleAnalytics:AccountId"]; if (!string.IsNullOrEmpty(gaTrackingId)) { ctx.Set("google_analytics_tracking_id", gaTrackingId); } var fbTrackingId = ConfigurationManager.AppSettings["FacebookTracker:AddPixelId"]; if (!string.IsNullOrEmpty(fbTrackingId)) { ctx.Set("facebook_tracking_id", fbTrackingId); } context.Set("vc_sitecontext", ctx); } await Next.Invoke(context); }