22using System . Diagnostics . CodeAnalysis ;
33using System . Globalization ;
44using System . Runtime . CompilerServices ;
5+ using Microsoft . Extensions . DependencyInjection ;
56using Microsoft . Extensions . Logging ;
67using Microsoft . Extensions . Options ;
78using Umbraco . Cms . Core . Configuration . Models ;
9+ using Umbraco . Cms . Core . DependencyInjection ;
810using Umbraco . Cms . Core . Models ;
911using Umbraco . Cms . Core . Persistence . Repositories ;
1012using Umbraco . Cms . Core . PublishedCache ;
@@ -28,6 +30,7 @@ public class DocumentUrlService : IDocumentUrlService
2830 private readonly IDocumentRepository _documentRepository ;
2931 private readonly ICoreScopeProvider _coreScopeProvider ;
3032 private readonly GlobalSettings _globalSettings ;
33+ private readonly WebRoutingSettings _webRoutingSettings ;
3134 private readonly UrlSegmentProviderCollection _urlSegmentProviderCollection ;
3235 private readonly IContentService _contentService ;
3336 private readonly IShortStringHelper _shortStringHelper ;
@@ -37,6 +40,7 @@ public class DocumentUrlService : IDocumentUrlService
3740 private readonly IDocumentNavigationQueryService _documentNavigationQueryService ;
3841 private readonly IPublishStatusQueryService _publishStatusQueryService ;
3942 private readonly IDomainCacheService _domainCacheService ;
43+ private readonly IDefaultCultureAccessor _defaultCultureAccessor ;
4044
4145 private readonly ConcurrentDictionary < string , PublishedDocumentUrlSegments > _cache = new ( ) ;
4246 private bool _isInitialized ;
@@ -96,6 +100,7 @@ public UrlSegment(string segment, bool isPrimary)
96100 /// <summary>
97101 /// Initializes a new instance of the <see cref="DocumentUrlService"/> class.
98102 /// </summary>
103+ [ Obsolete ( "Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19." ) ]
99104 public DocumentUrlService (
100105 ILogger < DocumentUrlService > logger ,
101106 IDocumentUrlRepository documentUrlRepository ,
@@ -111,12 +116,53 @@ public DocumentUrlService(
111116 IDocumentNavigationQueryService documentNavigationQueryService ,
112117 IPublishStatusQueryService publishStatusQueryService ,
113118 IDomainCacheService domainCacheService )
119+ : this (
120+ logger ,
121+ documentUrlRepository ,
122+ documentRepository ,
123+ coreScopeProvider ,
124+ globalSettings ,
125+ StaticServiceProvider . Instance . GetRequiredService < IOptions < WebRoutingSettings > > ( ) ,
126+ urlSegmentProviderCollection ,
127+ contentService ,
128+ shortStringHelper ,
129+ languageService ,
130+ keyValueService ,
131+ idKeyMap ,
132+ documentNavigationQueryService ,
133+ publishStatusQueryService ,
134+ domainCacheService ,
135+ StaticServiceProvider . Instance . GetRequiredService < IDefaultCultureAccessor > ( ) )
136+ {
137+ }
138+
139+ /// <summary>
140+ /// Initializes a new instance of the <see cref="DocumentUrlService"/> class.
141+ /// </summary>
142+ public DocumentUrlService (
143+ ILogger < DocumentUrlService > logger ,
144+ IDocumentUrlRepository documentUrlRepository ,
145+ IDocumentRepository documentRepository ,
146+ ICoreScopeProvider coreScopeProvider ,
147+ IOptions < GlobalSettings > globalSettings ,
148+ IOptions < WebRoutingSettings > webRoutingSettings ,
149+ UrlSegmentProviderCollection urlSegmentProviderCollection ,
150+ IContentService contentService ,
151+ IShortStringHelper shortStringHelper ,
152+ ILanguageService languageService ,
153+ IKeyValueService keyValueService ,
154+ IIdKeyMap idKeyMap ,
155+ IDocumentNavigationQueryService documentNavigationQueryService ,
156+ IPublishStatusQueryService publishStatusQueryService ,
157+ IDomainCacheService domainCacheService ,
158+ IDefaultCultureAccessor defaultCultureAccessor )
114159 {
115160 _logger = logger ;
116161 _documentUrlRepository = documentUrlRepository ;
117162 _documentRepository = documentRepository ;
118163 _coreScopeProvider = coreScopeProvider ;
119164 _globalSettings = globalSettings . Value ;
165+ _webRoutingSettings = webRoutingSettings . Value ;
120166 _urlSegmentProviderCollection = urlSegmentProviderCollection ;
121167 _contentService = contentService ;
122168 _shortStringHelper = shortStringHelper ;
@@ -126,6 +172,7 @@ public DocumentUrlService(
126172 _documentNavigationQueryService = documentNavigationQueryService ;
127173 _publishStatusQueryService = publishStatusQueryService ;
128174 _domainCacheService = domainCacheService ;
175+ _defaultCultureAccessor = defaultCultureAccessor ;
129176 }
130177
131178 /// <inheritdoc/>
@@ -494,6 +541,37 @@ public async Task DeleteUrlsFromCacheAsync(IEnumerable<Guid> documentKeysEnumera
494541 scope . Complete ( ) ;
495542 }
496543
544+ /// <inheritdoc/>
545+ public Guid ? GetDocumentKeyByUri ( Uri uri , bool isDraft )
546+ {
547+ IEnumerable < Domain > domains = _domainCacheService . GetAll ( false ) ;
548+ DomainAndUri ? domain = DomainUtilities . SelectDomain ( domains , uri , defaultCulture : _defaultCultureAccessor . DefaultCulture ) ;
549+
550+ string route ;
551+ if ( domain is not null )
552+ {
553+ route = domain . ContentId + DomainUtilities . PathRelativeToDomain ( domain . Uri , uri . GetAbsolutePathDecoded ( ) ) ;
554+ }
555+ else
556+ {
557+ // If we have configured strict domain matching, and a domain has not been found for the request configured on an ancestor node,
558+ // do not route the content by URL.
559+ if ( _webRoutingSettings . UseStrictDomainMatching )
560+ {
561+ return null ;
562+ }
563+
564+ // Default behaviour if strict domain matching is not enabled will be to route under the to the first root node found.
565+ route = uri . GetAbsolutePathDecoded ( ) ;
566+ }
567+
568+ return GetDocumentKeyByRoute (
569+ domain is null ? route : route [ domain . ContentId . ToString ( ) . Length ..] ,
570+ domain ? . Culture ,
571+ domain ? . ContentId ,
572+ isDraft ) ;
573+ }
574+
497575 /// <inheritdoc/>
498576 public Guid ? GetDocumentKeyByRoute ( string route , string ? culture , int ? documentStartNodeId , bool isDraft )
499577 {
0 commit comments