Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Umbraco.Core/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ public class MyEntityCacheRefresher : CacheRefresherBase<MyEntityCacheRefresher>
- `IMediaService` - Media operations
- `IDataTypeService` - Data type configuration
- `IUserService` - User management
- `ILocalizationService` - Languages and dictionary
- `ILanguageService` - Languages
- `IDictionaryItemService` - Dictionary items
- `IRelationService` - Entity relationships

#### Content Models
Expand Down
1 change: 0 additions & 1 deletion src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,7 @@
Services.AddUnique<IUserGroupService, UserGroupService>();
Services.AddUnique<IUserPermissionService, UserPermissionService>();
Services.AddUnique<IUserService, UserService>();
Services.AddUnique<IWebProfilerService, WebProfilerService>();

Check notice on line 296 in src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (v18/dev)

✅ Getting better: Large Method

AddCoreServices decreases from 236 to 235 lines of code, threshold = 70. Large functions with many lines of code are generally harder to understand and lower the code health. Avoid adding more lines to this function.
Services.AddUnique<ILocalizationService, LocalizationService>();
Services.AddUnique<IDictionaryItemService, DictionaryItemService>();
Services.AddUnique<IDataTypeContainerService, DataTypeContainerService>();
Services.AddUnique<IContentTypeContainerService, ContentTypeContainerService>();
Expand Down
34 changes: 16 additions & 18 deletions src/Umbraco.Core/Dictionary/DefaultCultureDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,39 @@
namespace Umbraco.Cms.Core.Dictionary;

/// <summary>
/// A culture dictionary that uses the Umbraco ILocalizationService
/// A culture dictionary that uses the Umbraco ILanguageService and IDictionaryItemService.
/// </summary>
/// <remarks>
/// TODO: The ICultureDictionary needs to represent the 'fast' way to do dictionary item retrieval - for front-end and
/// back office.
/// The ILocalizationService is the service used for interacting with this data from the database which isn't all that
/// fast
/// (even though there is caching involved, if there's lots of dictionary items the caching is not great)
/// ILanguageService and IDictionaryItemService are the services used for interacting with this data from the database
/// which isn't all that fast (even though there is caching involved, if there's lots of dictionary items the caching is
/// not great).
/// </remarks>
internal sealed class DefaultCultureDictionary : ICultureDictionary
{
private readonly ILocalizationService _localizationService;
private readonly ILanguageService _languageService;
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IAppCache _requestCache;
private readonly CultureInfo? _specificCulture;

/// <summary>
/// Default constructor which will use the current thread's culture
/// </summary>
/// <param name="localizationService"></param>
/// <param name="requestCache"></param>
public DefaultCultureDictionary(ILocalizationService localizationService, IAppCache requestCache)
public DefaultCultureDictionary(ILanguageService languageService, IDictionaryItemService dictionaryItemService, IAppCache requestCache)
{
_localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService));
_languageService = languageService ?? throw new ArgumentNullException(nameof(languageService));
_dictionaryItemService = dictionaryItemService ?? throw new ArgumentNullException(nameof(dictionaryItemService));
_requestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
}

/// <summary>
/// Constructor for testing to specify a static culture
/// </summary>
/// <param name="specificCulture"></param>
/// <param name="localizationService"></param>
/// <param name="requestCache"></param>
public DefaultCultureDictionary(CultureInfo specificCulture, ILocalizationService localizationService, IAppCache requestCache)
public DefaultCultureDictionary(CultureInfo specificCulture, ILanguageService languageService, IDictionaryItemService dictionaryItemService, IAppCache requestCache)
{
_localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService));
_languageService = languageService ?? throw new ArgumentNullException(nameof(languageService));
_dictionaryItemService = dictionaryItemService ?? throw new ArgumentNullException(nameof(dictionaryItemService));
_requestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
_specificCulture = specificCulture ?? throw new ArgumentNullException(nameof(specificCulture));
}
Expand All @@ -64,7 +62,7 @@ public DefaultCultureDictionary(CultureInfo specificCulture, ILocalizationServic
CultureInfo culture = Culture;
while (culture != CultureInfo.InvariantCulture)
{
ILanguage? language = _localizationService.GetLanguageByIsoCode(culture.Name);
ILanguage? language = _languageService.GetAsync(culture.Name).GetAwaiter().GetResult();
if (language != null)
{
return language;
Expand All @@ -85,7 +83,7 @@ public string this[string key]
{
get
{
IDictionaryItem? found = _localizationService.GetDictionaryItemByKey(key);
IDictionaryItem? found = _dictionaryItemService.GetAsync(key).GetAwaiter().GetResult();
if (found == null)
{
return string.Empty;
Expand Down Expand Up @@ -115,13 +113,13 @@ public IDictionary<string, string> GetChildren(string key)
{
var result = new Dictionary<string, string>();

IDictionaryItem? found = _localizationService.GetDictionaryItemByKey(key);
IDictionaryItem? found = _dictionaryItemService.GetAsync(key).GetAwaiter().GetResult();
if (found == null)
{
return result;
}

IEnumerable<IDictionaryItem>? children = _localizationService.GetDictionaryItemChildren(found.Key);
IEnumerable<IDictionaryItem>? children = _dictionaryItemService.GetChildrenAsync(found.Key).GetAwaiter().GetResult();
if (children == null)
{
return result;
Expand Down
15 changes: 9 additions & 6 deletions src/Umbraco.Core/Dictionary/DefaultCultureDictionaryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,27 @@ namespace Umbraco.Cms.Core.Dictionary;
public class DefaultCultureDictionaryFactory : ICultureDictionaryFactory
{
private readonly AppCaches _appCaches;
private readonly ILocalizationService _localizationService;
private readonly ILanguageService _languageService;
private readonly IDictionaryItemService _dictionaryItemService;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultCultureDictionaryFactory"/> class.
/// </summary>
/// <param name="localizationService">The localization service for accessing dictionary items.</param>
/// <param name="languageService">The language service.</param>
/// <param name="dictionaryItemService">The dictionary item service.</param>
/// <param name="appCaches">The application caches containing the request cache.</param>
public DefaultCultureDictionaryFactory(ILocalizationService localizationService, AppCaches appCaches)
public DefaultCultureDictionaryFactory(ILanguageService languageService, IDictionaryItemService dictionaryItemService, AppCaches appCaches)
{
_localizationService = localizationService;
_languageService = languageService;
_dictionaryItemService = dictionaryItemService;
_appCaches = appCaches;
}

/// <inheritdoc />
public ICultureDictionary CreateDictionary() =>
new DefaultCultureDictionary(_localizationService, _appCaches.RequestCache);
new DefaultCultureDictionary(_languageService, _dictionaryItemService, _appCaches.RequestCache);

/// <inheritdoc />
public ICultureDictionary CreateDictionary(CultureInfo specificCulture) =>
new DefaultCultureDictionary(specificCulture, _localizationService, _appCaches.RequestCache);
new DefaultCultureDictionary(specificCulture, _languageService, _dictionaryItemService, _appCaches.RequestCache);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent;
/// </summary>
public class PublishedValueFallback : IPublishedValueFallback
{
private readonly ILocalizationService? _localizationService;
private readonly ILanguageService? _languageService;
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly IPropertyRenderingContextAccessor _propertyRenderingContextAccessor;

Expand All @@ -23,7 +23,7 @@ public class PublishedValueFallback : IPublishedValueFallback
/// <param name="propertyRenderingContextAccessor">The property rendering context accessor.</param>
public PublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor, IPropertyRenderingContextAccessor propertyRenderingContextAccessor)
{
_localizationService = serviceContext.LocalizationService;
_languageService = serviceContext.LanguageService;
_variationContextAccessor = variationContextAccessor;
_propertyRenderingContextAccessor = propertyRenderingContextAccessor;
}
Expand Down Expand Up @@ -303,7 +303,7 @@ private bool TryGetValueWithLanguageFallback<T>(TryGetValueForCultureAndSegment<

var visited = new HashSet<string>();

ILanguage? language = culture is not null ? _localizationService?.GetLanguageByIsoCode(culture) : null;
ILanguage? language = culture is not null ? _languageService?.GetAsync(culture).GetAwaiter().GetResult() : null;
if (language == null)
{
return false;
Expand All @@ -324,7 +324,7 @@ private bool TryGetValueWithLanguageFallback<T>(TryGetValueForCultureAndSegment<

visited.Add(language2IsoCode);

ILanguage? language2 = _localizationService?.GetLanguageByIsoCode(language2IsoCode);
ILanguage? language2 = _languageService?.GetAsync(language2IsoCode).GetAwaiter().GetResult();
if (language2 == null)
{
return false;
Expand Down Expand Up @@ -371,7 +371,7 @@ private bool TryGetValueWithDefaultLanguageFallback<T>(TryGetValueForCultureAndS
return false;
}

var defaultCulture = _localizationService?.GetDefaultLanguageIsoCode();
var defaultCulture = _languageService?.GetDefaultIsoCodeAsync().GetAwaiter().GetResult();
if (defaultCulture.IsNullOrWhiteSpace())
{
return false;
Expand Down
6 changes: 3 additions & 3 deletions src/Umbraco.Core/Models/UserExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,14 @@ public static bool HasAccessToSensitiveData(this IUser user)
}

/// <summary>
/// Calculate start nodes, combining groups' and user's, and excluding what's in the bin
/// Calculate the set of language ids the user is allowed to access, combining group permissions.
/// </summary>
public static int[] CalculateAllowedLanguageIds(this IUser user, ILocalizationService localizationService)
public static async Task<int[]> CalculateAllowedLanguageIdsAsync(this IUser user, ILanguageService languageService)
{
var hasAccessToAllLanguages = user.Groups.Any(x => x.HasAccessToAllLanguages);

return hasAccessToAllLanguages
? localizationService.GetAllLanguages().Select(x => x.Id).ToArray()
? (await languageService.GetAllAsync()).Select(x => x.Id).ToArray()
: user.Groups.SelectMany(x => x.AllowedLanguages).Distinct().ToArray();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Umbraco.Cms.Core.Notifications;
/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Delete (IDictionaryItem overload) method is called in the API, after the dictionary items has been deleted.
/// A notification that is used to trigger the IDictionaryItemService when a dictionary item is deleted via the API, after the dictionary item has been deleted.
/// </summary>
public class DictionaryItemDeletedNotification : DeletedNotification<IDictionaryItem>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace Umbraco.Cms.Core.Notifications;

/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Delete (IDictionaryItem overload) method is called in the API.
/// A notification that is used to trigger the IDictionaryItemService when a dictionary item is deleted via the API.
/// </summary>
/// <remarks>
/// This notification is cancelable, allowing handlers to prevent the delete operation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace Umbraco.Cms.Core.Notifications;

/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Save (IDictionaryItem overload) method is called in the API and the data has been persisted.
/// A notification that is used to trigger the IDictionaryItemService when a dictionary item is created or updated via the API, after data has been persisted.
/// </summary>
public class DictionaryItemSavedNotification : SavedNotification<IDictionaryItem>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace Umbraco.Cms.Core.Notifications;

/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Save (IDictionaryItem overload) method is called in the API.
/// A notification that is used to trigger the IDictionaryItemService when a dictionary item is created or updated via the API.
/// </summary>
/// <remarks>
/// This notification is cancelable, allowing handlers to prevent the save operation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace Umbraco.Cms.Core.Notifications;

/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Delete (ILanguage overload) method is called in the API, after the languages have been deleted.
/// A notification that is used to trigger the ILanguageService when a language is deleted via the API, after the language has been deleted.
/// </summary>
public class LanguageDeletedNotification : DeletedNotification<ILanguage>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Umbraco.Cms.Core.Notifications;
/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Delete (ILanguage overload) method is called in the API.
/// A notification that is used to trigger the ILanguageService when a language is deleted via the API.
/// </summary>
public class LanguageDeletingNotification : DeletingNotification<ILanguage>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Umbraco.Cms.Core.Notifications;
/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Save (ILanguage overload) method is called in the API, after data has been persisted.
/// A notification that is used to trigger the ILanguageService when a language is created or updated via the API, after data has been persisted.
/// </summary>
public class LanguageSavedNotification : SavedNotification<ILanguage>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Umbraco.Cms.Core.Notifications;
/// <summary>
/// A notification that is used to trigger the ILocalizationService when the Save (ILanguage overload) method is called in the API.
/// A notification that is used to trigger the ILanguageService when a language is created or updated via the API.
/// </summary>
public class LanguageSavingNotification : SavingNotification<ILanguage>
{
Expand Down
Loading
Loading