Try your search with a different keyword or use * as a wildcard.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Directory;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Tax;
using Nop.Core.Domain.Vendors;
using Nop.Core.Events;
using Nop.Core.Http;
using Nop.Core.Security;
using Nop.Services.Authentication;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.ScheduleTasks;
using Nop.Services.Stores;
using Nop.Services.Vendors;
using Nop.Web.Framework.Globalization;
namespace Nop.Web.Framework;
///
/// Represents work context for web application
///
public partial class WebWorkContext : IWorkContext
{
#region Fields
protected readonly CookieSettings _cookieSettings;
protected readonly CurrencySettings _currencySettings;
protected readonly IAuthenticationService _authenticationService;
protected readonly ICurrencyService _currencyService;
protected readonly ICustomerService _customerService;
protected readonly IEventPublisher _eventPublisher;
protected readonly IGenericAttributeService _genericAttributeService;
protected readonly IHttpContextAccessor _httpContextAccessor;
protected readonly ILanguageService _languageService;
protected readonly IStoreContext _storeContext;
protected readonly IStoreMappingService _storeMappingService;
protected readonly IUserAgentHelper _userAgentHelper;
protected readonly IVendorService _vendorService;
protected readonly IWebHelper _webHelper;
protected readonly LocalizationSettings _localizationSettings;
protected readonly TaxSettings _taxSettings;
protected Customer _cachedCustomer;
protected Customer _originalCustomerIfImpersonated;
protected Vendor _cachedVendor;
protected Language _cachedLanguage;
protected Currency _cachedCurrency;
protected TaxDisplayType? _cachedTaxDisplayType;
#endregion
#region Ctor
public WebWorkContext(CookieSettings cookieSettings,
CurrencySettings currencySettings,
IAuthenticationService authenticationService,
ICurrencyService currencyService,
ICustomerService customerService,
IEventPublisher eventPublisher,
IGenericAttributeService genericAttributeService,
IHttpContextAccessor httpContextAccessor,
ILanguageService languageService,
IStoreContext storeContext,
IStoreMappingService storeMappingService,
IUserAgentHelper userAgentHelper,
IVendorService vendorService,
IWebHelper webHelper,
LocalizationSettings localizationSettings,
TaxSettings taxSettings)
{
_cookieSettings = cookieSettings;
_currencySettings = currencySettings;
_authenticationService = authenticationService;
_currencyService = currencyService;
_customerService = customerService;
_eventPublisher = eventPublisher;
_genericAttributeService = genericAttributeService;
_httpContextAccessor = httpContextAccessor;
_languageService = languageService;
_storeContext = storeContext;
_storeMappingService = storeMappingService;
_userAgentHelper = userAgentHelper;
_vendorService = vendorService;
_webHelper = webHelper;
_localizationSettings = localizationSettings;
_taxSettings = taxSettings;
}
#endregion
#region Utilities
///
/// Get nop customer cookie
///
/// String value of cookie
protected virtual string GetCustomerCookie()
{
var cookieName = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.CustomerCookie}";
return _httpContextAccessor.HttpContext?.Request?.Cookies[cookieName];
}
///
/// Set nop customer cookie
///
/// Guid of the customer
protected virtual void SetCustomerCookie(Guid customerGuid)
{
if (_httpContextAccessor.HttpContext?.Response.HasStarted ?? true)
return;
//delete current cookie value
var cookieName = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.CustomerCookie}";
_httpContextAccessor.HttpContext.Response.Cookies.Delete(cookieName);
//get date of cookie expiration
var cookieExpires = _cookieSettings.CustomerCookieExpires;
var cookieExpiresDate = DateTime.Now.AddHours(cookieExpires);
//if passed guid is empty set cookie as expired
if (customerGuid == Guid.Empty)
cookieExpiresDate = DateTime.Now.AddMonths(-1);
//set new cookie value
var options = new CookieOptions
{
HttpOnly = true,
Expires = cookieExpiresDate,
Secure = _webHelper.IsCurrentConnectionSecured()
};
_httpContextAccessor.HttpContext.Response.Cookies.Append(cookieName, customerGuid.ToString(), options);
}
///
/// Set language culture cookie
///
/// Language
protected virtual void SetLanguageCookie(Language language)
{
if (_httpContextAccessor.HttpContext?.Response.HasStarted ?? true)
return;
//delete current cookie value
var cookieName = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.CultureCookie}";
_httpContextAccessor.HttpContext.Response.Cookies.Delete(cookieName);
if (string.IsNullOrEmpty(language?.LanguageCulture))
return;
//set new cookie value
var value = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(language.LanguageCulture));
var options = new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) };
_httpContextAccessor.HttpContext.Response.Cookies.Append(cookieName, value, options);
}
///
/// Get language from the request
///
///
/// A task that represents the asynchronous operation
/// The task result contains the found language
///
protected virtual async Task GetLanguageFromRequestAsync()
{
var requestCultureFeature = _httpContextAccessor.HttpContext?.Features.Get();
if (requestCultureFeature is null)
return null;
//whether we should detect the current language by customer settings
if (requestCultureFeature.Provider is not NopSeoUrlCultureProvider && !_localizationSettings.AutomaticallyDetectLanguage)
return null;
//get request culture
if (requestCultureFeature.RequestCulture is null)
return null;
//try to get language by culture name
var requestLanguage = (await _languageService.GetAllLanguagesAsync()).FirstOrDefault(language =>
language.LanguageCulture.Equals(requestCultureFeature.RequestCulture.Culture.Name, StringComparison.InvariantCultureIgnoreCase));
//check language availability
if (requestLanguage == null || !requestLanguage.Published || !await _storeMappingService.AuthorizeAsync(requestLanguage))
return null;
return requestLanguage;
}
#endregion
#region Properties
///
/// Gets the current customer
///
/// A task that represents the asynchronous operation
public virtual async Task GetCurrentCustomerAsync()
{
//whether there is a cached value
if (_cachedCustomer != null)
return _cachedCustomer;
await SetCurrentCustomerAsync();
return _cachedCustomer;
}
///
/// Sets the current customer
///
/// Current customer
/// A task that represents the asynchronous operation
public virtual async Task SetCurrentCustomerAsync(Customer customer = null)
{
if (customer == null)
{
//check whether request is made by a background (schedule) task
if (_httpContextAccessor.HttpContext?.Request
?.Path.Equals(new PathString($"/{NopTaskDefaults.ScheduleTaskPath}"), StringComparison.InvariantCultureIgnoreCase)
?? true)
{
//in this case return built-in customer record for background task
customer = await _customerService.GetOrCreateBackgroundTaskUserAsync();
}
if (customer == null || customer.Deleted || !customer.Active || customer.RequireReLogin)
{
//check whether request is made by a search engine, in this case return built-in customer record for search engines
if (_userAgentHelper.IsSearchEngine())
customer = await _customerService.GetOrCreateSearchEngineUserAsync();
}
if (customer == null || customer.Deleted || !customer.Active || customer.RequireReLogin)
{
//try to get registered user
customer = await _authenticationService.GetAuthenticatedCustomerAsync();
}
if (customer != null && !customer.Deleted && customer.Active && !customer.RequireReLogin)
{
//get impersonate user if required
var impersonatedCustomerId = await _genericAttributeService
.GetAttributeAsync(customer, NopCustomerDefaults.ImpersonatedCustomerIdAttribute);
if (impersonatedCustomerId.HasValue && impersonatedCustomerId.Value > 0)
{
var impersonatedCustomer = await _customerService.GetCustomerByIdAsync(impersonatedCustomerId.Value);
if (impersonatedCustomer != null && !impersonatedCustomer.Deleted &&
impersonatedCustomer.Active &&
!impersonatedCustomer.RequireReLogin)
{
//set impersonated customer
_originalCustomerIfImpersonated = customer;
customer = impersonatedCustomer;
}
}
}
if (customer == null || customer.Deleted || !customer.Active || customer.RequireReLogin)
{
//get guest customer
var customerCookie = GetCustomerCookie();
if (Guid.TryParse(customerCookie, out var customerGuid))
{
//get customer from cookie (should not be registered)
var customerByCookie = await _customerService.GetCustomerByGuidAsync(customerGuid);
if (customerByCookie != null && !await _customerService.IsRegisteredAsync(customerByCookie))
customer = customerByCookie;
}
}
if (customer == null || customer.Deleted || !customer.Active || customer.RequireReLogin)
{
//create guest if not exists
customer = await _customerService.InsertGuestCustomerAsync();
}
}
if (!customer.Deleted && customer.Active && !customer.RequireReLogin)
{
//set customer cookie
SetCustomerCookie(customer.CustomerGuid);
//cache the found customer
_cachedCustomer = customer;
}
}
///
/// Gets the original customer (in case the current one is impersonated)
///
public virtual Customer OriginalCustomerIfImpersonated => _originalCustomerIfImpersonated;
///
/// Gets the current vendor (logged-in manager)
///
/// A task that represents the asynchronous operation
public virtual async Task GetCurrentVendorAsync()
{
//whether there is a cached value
if (_cachedVendor != null)
return _cachedVendor;
var customer = await GetCurrentCustomerAsync();
if (customer == null)
return null;
//check vendor availability
var vendor = await _vendorService.GetVendorByIdAsync(customer.VendorId);
if (vendor == null || vendor.Deleted || !vendor.Active)
return null;
//cache the found vendor
_cachedVendor = vendor;
return _cachedVendor;
}
///
/// Sets current user working language
///
/// Language
/// A task that represents the asynchronous operation
public virtual async Task SetWorkingLanguageAsync(Language language)
{
//save passed language identifier
var customer = await GetCurrentCustomerAsync();
if (!customer.IsSystemAccount)
{
customer.LanguageId = language?.Id;
await _customerService.UpdateCustomerAsync(customer);
//raise event
await _eventPublisher.PublishAsync(new CustomerChangeWorkingLanguageEvent(customer));
}
//set cookie
SetLanguageCookie(language);
//then reset the cached value
_cachedLanguage = null;
}
///
/// Gets current user working language
///
/// A task that represents the asynchronous operation
public virtual async Task GetWorkingLanguageAsync()
{
//whether there is a cached value
if (_cachedLanguage != null)
return _cachedLanguage;
var customer = await GetCurrentCustomerAsync();
var store = await _storeContext.GetCurrentStoreAsync();
//whether we should detect the language from the request
var detectedLanguage = await GetLanguageFromRequestAsync();
//get current saved language identifier
var currentLanguageId = customer.LanguageId;
//if the language is detected we need to save it
if (detectedLanguage != null)
{
//save the detected language identifier if it differs from the current one
if (detectedLanguage.Id != currentLanguageId)
await SetWorkingLanguageAsync(detectedLanguage);
}
else
{
var allStoreLanguages = await _languageService.GetAllLanguagesAsync(storeId: store.Id);
//check customer language availability
detectedLanguage = allStoreLanguages.FirstOrDefault(language => language.Id == currentLanguageId);
//it not found, then try to get the default language for the current store (if specified)
detectedLanguage ??= allStoreLanguages.FirstOrDefault(language => language.Id == store.DefaultLanguageId);
//if the default language for the current store not found, then try to get the first one
detectedLanguage ??= allStoreLanguages.FirstOrDefault();
//if there are no languages for the current store try to get the first one regardless of the store
detectedLanguage ??= (await _languageService.GetAllLanguagesAsync()).FirstOrDefault();
SetLanguageCookie(detectedLanguage);
}
//cache the found language
_cachedLanguage = detectedLanguage;
return _cachedLanguage;
}
///
/// Gets current user working currency
///
/// A task that represents the asynchronous operation
public virtual async Task GetWorkingCurrencyAsync()
{
//whether there is a cached value
if (_cachedCurrency != null)
return _cachedCurrency;
var adminAreaUrl = $"{_webHelper.GetStoreLocation()}admin";
//return primary store currency when we're in admin area/mode
if (_webHelper.GetThisPageUrl(false).StartsWith(adminAreaUrl, StringComparison.InvariantCultureIgnoreCase))
{
var primaryStoreCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
if (primaryStoreCurrency != null)
{
_cachedCurrency = primaryStoreCurrency;
return primaryStoreCurrency;
}
}
var customer = await GetCurrentCustomerAsync();
var store = await _storeContext.GetCurrentStoreAsync();
if (customer.IsSearchEngineAccount())
{
_cachedCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId)
?? (await _currencyService.GetAllCurrenciesAsync(storeId: store.Id)).FirstOrDefault();
return _cachedCurrency;
}
var allStoreCurrencies = await _currencyService.GetAllCurrenciesAsync(storeId: store.Id);
//check customer currency availability
var customerCurrency = allStoreCurrencies.FirstOrDefault(currency => currency.Id == customer.CurrencyId);
if (customerCurrency == null)
{
//it not found, then try to get the default currency for the current language (if specified)
var language = await GetWorkingLanguageAsync();
customerCurrency = allStoreCurrencies
.FirstOrDefault(currency => currency.Id == language.DefaultCurrencyId);
}
//if the default currency for the current store not found, then try to get the first one
customerCurrency ??= allStoreCurrencies.FirstOrDefault();
//if there are no currencies for the current store try to get the first one regardless of the store
customerCurrency ??= (await _currencyService.GetAllCurrenciesAsync()).FirstOrDefault();
//cache the found currency
_cachedCurrency = customerCurrency;
return _cachedCurrency;
}
///
/// Sets current user working currency
///
/// Currency
/// A task that represents the asynchronous operation
public virtual async Task SetWorkingCurrencyAsync(Currency currency)
{
//save passed currency identifier
var customer = await GetCurrentCustomerAsync();
if (customer.IsSearchEngineAccount())
return;
customer.CurrencyId = currency?.Id;
await _customerService.UpdateCustomerAsync(customer);
//then reset the cached value
_cachedCurrency = null;
}
///
/// Gets or sets current tax display type
///
/// A task that represents the asynchronous operation
public virtual async Task GetTaxDisplayTypeAsync()
{
//whether there is a cached value
if (_cachedTaxDisplayType.HasValue)
return _cachedTaxDisplayType.Value;
var customer = await GetCurrentCustomerAsync();
var taxDisplayType = await _customerService.GetCustomerTaxDisplayTypeAsync(customer);
//cache the value
_cachedTaxDisplayType = taxDisplayType;
return _cachedTaxDisplayType.Value;
}
/// A task that represents the asynchronous operation
public virtual async Task SetTaxDisplayTypeAsync(TaxDisplayType taxDisplayType)
{
//whether customers are allowed to select tax display type
if (!_taxSettings.AllowCustomersToSelectTaxDisplayType)
return;
//save passed value
var customer = await GetCurrentCustomerAsync();
customer.TaxDisplayType = taxDisplayType;
await _customerService.UpdateCustomerAsync(customer);
//then reset the cached value
_cachedTaxDisplayType = null;
}
///
/// Gets or sets value indicating whether we're in admin area
///
public virtual bool IsAdmin { get; set; }
#endregion
}