private async Task GetOverrideKeysInternal( object settings, object model, int storeId, bool isRootModel, Func <string, string> propertyNameMapper, int?localeIndex) { if (storeId <= 0) { // Single store mode -> there are no overrides. return; } var data = Data ?? new StoreDependingSettingData(); var settingType = settings.GetType(); var modelType = model.GetType(); var settingName = settingType.Name; var modelProperties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance); var localizedModelLocal = model as ILocalizedLocaleModel; foreach (var prop in modelProperties) { var name = propertyNameMapper?.Invoke(prop.Name) ?? prop.Name; var settingProperty = settingType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); if (settingProperty == null) { // Setting is not configurable or missing or whatever... however we don't need the override info. continue; } string key = null; if (localizedModelLocal == null) { key = settingName + "." + name; if (await _settingService.GetSettingByKeyAsync <string>(key, storeId: storeId) == null) { key = null; } } else if (localeIndex.HasValue) { var value = await _leService.GetLocalizedValueAsync(localizedModelLocal.LanguageId, storeId, settingName, name); if (!string.IsNullOrEmpty(value)) { key = settingName + "." + "Locales[" + localeIndex.ToString() + "]." + name; } } if (key != null) { data.OverrideSettingKeys.Add(key); } } if (isRootModel) { data.ActiveStoreScopeConfiguration = storeId; data.RootSettingClass = settingName; _viewData[ViewDataKey] = data; } if (model is ILocalizedModel) { var localesProperty = modelType.GetProperty("Locales", BindingFlags.Public | BindingFlags.Instance); if (localesProperty != null) { if (localesProperty.GetValue(model) is IEnumerable <ILocalizedLocaleModel> locales) { int i = 0; foreach (var locale in locales) { await GetOverrideKeysInternal(settings, locale, storeId, false, propertyNameMapper, i); i++; } } } } }
/// <summary> /// Get localized property of an entity /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <typeparam name="TPropType">Property type</typeparam> /// <param name="entity">Entity</param> /// <param name="keySelector">Key selector</param> /// <param name="languageId">Language identifier; pass null to use the current working language; pass 0 to get standard language value</param> /// <param name="returnDefaultValue">A value indicating whether to return default value (if localized is not found)</param> /// <param name="ensureTwoPublishedLanguages">A value indicating whether to ensure that we have at least two published languages; otherwise, load only default value</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the localized property /// </returns> public virtual async Task <TPropType> GetLocalizedAsync <TEntity, TPropType>(TEntity entity, Expression <Func <TEntity, TPropType> > keySelector, int?languageId = null, bool returnDefaultValue = true, bool ensureTwoPublishedLanguages = true) where TEntity : BaseEntity, ILocalizedEntity { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } if (keySelector.Body is not MemberExpression member) { throw new ArgumentException($"Expression '{keySelector}' refers to a method, not a property."); } if (member.Member is not PropertyInfo propInfo) { throw new ArgumentException($"Expression '{keySelector}' refers to a field, not a property."); } var result = default(TPropType); var resultStr = string.Empty; var localeKeyGroup = entity.GetType().Name; var localeKey = propInfo.Name; var workingLanguage = await _workContext.GetWorkingLanguageAsync(); if (!languageId.HasValue) { languageId = workingLanguage.Id; } if (languageId > 0) { //ensure that we have at least two published languages var loadLocalizedValue = true; if (ensureTwoPublishedLanguages) { var totalPublishedLanguages = (await _languageService.GetAllLanguagesAsync()).Count; loadLocalizedValue = totalPublishedLanguages >= 2; } //localized value if (loadLocalizedValue) { resultStr = await _localizedEntityService .GetLocalizedValueAsync(languageId.Value, entity.Id, localeKeyGroup, localeKey); if (!string.IsNullOrEmpty(resultStr)) { result = CommonHelper.To <TPropType>(resultStr); } } } //set default value if required if (!string.IsNullOrEmpty(resultStr) || !returnDefaultValue) { return(result); } var localizer = keySelector.Compile(); result = localizer(entity); return(result); }