diff --git a/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs b/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs index c3e779b0d715..4c4a3dbca684 100644 --- a/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs +++ b/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs @@ -15,54 +15,102 @@ namespace Umbraco.Cms.Core.Routing; /// -/// Provides urls. +/// Provides URLs. /// public class NewDefaultUrlProvider : IUrlProvider { - private readonly ILocalizationService _localizationService; private readonly IPublishedContentCache _publishedContentCache; private readonly IDomainCache _domainCache; private readonly IIdKeyMap _idKeyMap; private readonly IDocumentUrlService _documentUrlService; private readonly IDocumentNavigationQueryService _navigationQueryService; private readonly IPublishedContentStatusFilteringService _publishedContentStatusFilteringService; - private readonly ILocalizedTextService? _localizedTextService; private readonly ILogger _logger; private readonly ISiteDomainMapper _siteDomainMapper; private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly UriUtility _uriUtility; private RequestHandlerSettings _requestSettings; + private readonly ILanguageService _languageService; + // TODO (V17): When removing the obsolete constructors, remove the unused localizationService parameter from the constructor (we can't do it now + // because it is used in the obsolete constructors and leads to an ambigious constructor error). + // See also if we can make GetUrlFromRoute asynchronous and avoid the GetAwaiter().GetResult() in when using ILanguageService. + + /// + /// Initializes a new instance of the class. + /// public NewDefaultUrlProvider( IOptionsMonitor requestSettings, ILogger logger, ISiteDomainMapper siteDomainMapper, IUmbracoContextAccessor umbracoContextAccessor, UriUtility uriUtility, +#pragma warning disable CS0618 // Type or member is obsolete +#pragma warning disable IDE0060 // Remove unused parameter ILocalizationService localizationService, +#pragma warning restore IDE0060 // Remove unused parameter +#pragma warning restore CS0618 // Type or member is obsolete IPublishedContentCache publishedContentCache, IDomainCache domainCache, IIdKeyMap idKeyMap, IDocumentUrlService documentUrlService, IDocumentNavigationQueryService navigationQueryService, - IPublishedContentStatusFilteringService publishedContentStatusFilteringService) + IPublishedContentStatusFilteringService publishedContentStatusFilteringService, + ILanguageService languageService) { _requestSettings = requestSettings.CurrentValue; _logger = logger; _siteDomainMapper = siteDomainMapper; _umbracoContextAccessor = umbracoContextAccessor; _uriUtility = uriUtility; - _localizationService = localizationService; _publishedContentCache = publishedContentCache; _domainCache = domainCache; _idKeyMap = idKeyMap; _documentUrlService = documentUrlService; _navigationQueryService = navigationQueryService; _publishedContentStatusFilteringService = publishedContentStatusFilteringService; + _languageService = languageService; requestSettings.OnChange(x => _requestSettings = x); } + /// + /// Initializes a new instance of the class. + /// + [Obsolete("Use the non-obsolete constructor. Scheduled for removal in V17.")] + public NewDefaultUrlProvider( + IOptionsMonitor requestSettings, + ILogger logger, + ISiteDomainMapper siteDomainMapper, + IUmbracoContextAccessor umbracoContextAccessor, + UriUtility uriUtility, + ILocalizationService localizationService, + IPublishedContentCache publishedContentCache, + IDomainCache domainCache, + IIdKeyMap idKeyMap, + IDocumentUrlService documentUrlService, + IDocumentNavigationQueryService navigationQueryService, + IPublishedContentStatusFilteringService publishedContentStatusFilteringService) + : this( + requestSettings, + logger, + siteDomainMapper, + umbracoContextAccessor, + uriUtility, + localizationService, + publishedContentCache, + domainCache, + idKeyMap, + documentUrlService, + navigationQueryService, + publishedContentStatusFilteringService, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + + /// + /// Initializes a new instance of the class. + /// [Obsolete("Use the non-obsolete constructor. Scheduled for removal in V17.")] public NewDefaultUrlProvider( IOptionsMonitor requestSettings, @@ -92,8 +140,6 @@ public NewDefaultUrlProvider( { } - #region GetOtherUrls - /// /// Gets the other URLs of a published content. /// @@ -108,14 +154,14 @@ public NewDefaultUrlProvider( /// public virtual IEnumerable GetOtherUrls(int id, Uri current) { - var keyAttempt = _idKeyMap.GetKeyForId(id, UmbracoObjectTypes.Document); + Attempt keyAttempt = _idKeyMap.GetKeyForId(id, UmbracoObjectTypes.Document); if (keyAttempt.Success is false) { yield break; } - var key = keyAttempt.Result; + Guid key = keyAttempt.Result; IPublishedContent? node = _publishedContentCache.GetById(key); if (node == null) @@ -156,7 +202,7 @@ public virtual IEnumerable GetOtherUrls(int id, Uri current) // need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned) var pos = route.IndexOf('/', StringComparison.Ordinal); - var path = pos == 0 ? route : route.Substring(pos); + var path = pos == 0 ? route : route[pos..]; var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path)); uri = _uriUtility.UriFromUmbraco(uri, _requestSettings); @@ -178,17 +224,9 @@ public virtual IEnumerable GetOtherUrls(int id, Uri current) private string GetLegacyRouteFormatById(Guid key, string? culture) { var isDraft = _umbracoContextAccessor.GetRequiredUmbracoContext().InPreviewMode; - - return _documentUrlService.GetLegacyRouteFormat(key, culture, isDraft); - - } - #endregion - - #region GetUrl - /// public virtual UrlInfo? GetUrl(IPublishedContent content, UrlMode mode, string? culture, Uri current) { @@ -217,6 +255,9 @@ private string GetLegacyRouteFormatById(Guid key, string? culture) return GetUrlFromRoute(route, content.Id, current, mode, culture); } + /// + /// Gets the URL from the provided route. + /// internal UrlInfo? GetUrlFromRoute( string? route, int id, @@ -226,7 +267,7 @@ private string GetLegacyRouteFormatById(Guid key, string? culture) { if (string.IsNullOrWhiteSpace(route) || route.Equals("#")) { - if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) + if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug( "Couldn't find any page with nodeId={NodeId}. This is most likely caused by the page not being published.", @@ -248,7 +289,7 @@ private string GetLegacyRouteFormatById(Guid key, string? culture) current, culture); - var defaultCulture = _localizationService.GetDefaultLanguageIsoCode(); + var defaultCulture = _languageService.GetDefaultIsoCodeAsync().GetAwaiter().GetResult(); if (domainUri is not null || string.IsNullOrEmpty(culture) || culture.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase)) @@ -260,10 +301,6 @@ private string GetLegacyRouteFormatById(Guid key, string? culture) return null; } - #endregion - - #region Utilities - private Uri AssembleUrl(DomainAndUri? domainUri, string path, Uri current, UrlMode mode) { Uri uri; @@ -331,6 +368,4 @@ private string CombinePaths(string path1, string path2) var path = path1.TrimEnd(Constants.CharArrays.ForwardSlash) + path2; return path == "/" ? path : path.TrimEnd(Constants.CharArrays.ForwardSlash); } - - #endregion }