From f6984438a01fb8a25b95c2d7b13e3093d80461ae Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 27 Apr 2018 15:26:50 +1000 Subject: [PATCH] Fixes cases where there are no domains assigned, ensures there can't be duplicate URLs returned to the UI --- .../PublishedCache/NuCache/ContentCache.cs | 6 ++-- src/Umbraco.Web/Routing/AliasUrlProvider.cs | 9 ++++-- src/Umbraco.Web/Routing/DefaultUrlProvider.cs | 32 ++++++++++--------- .../Routing/UrlProviderExtensions.cs | 9 ++++-- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs index 37b8e97a28..c7661a3f28 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs @@ -104,8 +104,8 @@ namespace Umbraco.Web.PublishedCache.NuCache // hideTopLevelNode = support legacy stuff, look for /*/path/to/node // else normal, look for /path/to/node content = hideTopLevelNode.Value - ? GetAtRoot(preview).SelectMany(x => x.Children).FirstOrDefault(x => x.UrlName == parts[0]) - : GetAtRoot(preview).FirstOrDefault(x => x.UrlName == parts[0]); + ? GetAtRoot(preview).SelectMany(x => x.Children).FirstOrDefault(x => x.GetUrlName(_localizationService, culture) == parts[0]) + : GetAtRoot(preview).FirstOrDefault(x => x.GetUrlName(_localizationService, culture) == parts[0]); content = FollowRoute(content, parts, 1, culture); } @@ -114,7 +114,7 @@ namespace Umbraco.Web.PublishedCache.NuCache // have to look for /foo (see note in ApplyHideTopLevelNodeFromPath). if (content == null && hideTopLevelNode.Value && parts.Length == 1) { - content = GetAtRoot(preview).FirstOrDefault(x => x.UrlName == parts[0]); + content = GetAtRoot(preview).FirstOrDefault(x => x.GetUrlName(_localizationService, culture) == parts[0]); } return content; diff --git a/src/Umbraco.Web/Routing/AliasUrlProvider.cs b/src/Umbraco.Web/Routing/AliasUrlProvider.cs index 5e3f8ea919..4b7cb48add 100644 --- a/src/Umbraco.Web/Routing/AliasUrlProvider.cs +++ b/src/Umbraco.Web/Routing/AliasUrlProvider.cs @@ -90,8 +90,12 @@ namespace Umbraco.Web.Routing if (domainUris == null) { - var path = "/" + node.Value(Constants.Conventions.Content.UrlAlias); - var uri = new Uri(path, UriKind.Relative); + var umbracoUrlName = node.Value(Constants.Conventions.Content.UrlAlias); + if (string.IsNullOrWhiteSpace(umbracoUrlName)) + return Enumerable.Empty(); + + var path = "/" + umbracoUrlName; + var uri = new Uri(path, UriKind.Relative); return new[] { UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString() }; } else @@ -107,7 +111,6 @@ namespace Umbraco.Web.Routing result.Add(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString()); } } - return result; } } diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index 6a01250221..e09f343555 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -94,23 +94,25 @@ namespace Umbraco.Web.Routing /// public virtual IEnumerable GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current) { - var node = umbracoContext.ContentCache.GetById(id); + //get the invariant route for this item, this will give us the Id of it's domain node if one is assigned + var invariantRoute = umbracoContext.ContentCache.GetRouteById(id); + + if (string.IsNullOrWhiteSpace(invariantRoute)) + { + _logger.Debug(() => $"Couldn't find any page with nodeId={id}. This is most likely caused by the page not being published."); + return null; + } + var domainHelper = umbracoContext.GetDomainHelper(_siteDomainHelper); - var n = node; - var domainUris = domainHelper.DomainsForNode(n.Id, current, false); - while (domainUris == null && n != null) // n is null at root - { - // move to parent node - n = n.Parent; - domainUris = n == null ? null : domainHelper.DomainsForNode(n.Id, current); - } + // extract domainUri and path + // route is / or / + var pos = invariantRoute.IndexOf('/'); + var path = pos == 0 ? invariantRoute : invariantRoute.Substring(pos); + var domainUris = pos == 0 ? null : domainHelper.DomainsForNode(int.Parse(invariantRoute.Substring(0, pos)), current); - if (domainUris == null) - { - //there are no domains, exit + if (domainUris ==null) return Enumerable.Empty(); - } var result = new List(); foreach (var d in domainUris) @@ -120,8 +122,8 @@ namespace Umbraco.Web.Routing if (route == null) continue; //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('/'); - var path = pos == 0 ? route : route.Substring(pos); + pos = route.IndexOf('/'); + path = pos == 0 ? route : route.Substring(pos); var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path)); uri = UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index a71bb51ddc..f13e02381f 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -29,7 +29,7 @@ namespace Umbraco.Web.Routing if (contentService == null) throw new ArgumentNullException(nameof(contentService)); if (logger == null) throw new ArgumentNullException(nameof(logger)); - var urls = new List(); + var urls = new HashSet(); if (content.Published == false) { @@ -104,8 +104,11 @@ namespace Umbraco.Web.Routing } else { - urls.Add(url); - urls.AddRange(urlProvider.GetOtherUrls(content.Id)); + urls.Add(url); + foreach(var otherUrl in urlProvider.GetOtherUrls(content.Id)) + { + urls.Add(otherUrl); + } } } return urls;