using System; using System.Collections.Generic; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core; using Umbraco.Core.Logging; using LightInject; using Umbraco.Web.Composing; namespace Umbraco.Web.Routing { internal static class UrlProviderExtensions { // fixme inject private static ILocalizedTextService TextService => Current.Services.TextService; private static IContentService ContentService => Current.Services.ContentService; private static ILogger Logger => Current.Logger; /// /// Gets the URLs for the content item /// /// /// /// /// /// Use this when displaying URLs, if there are errors genertaing the urls the urls themselves will /// contain the errors. /// public static IEnumerable GetContentUrls(this IContent content, UmbracoContext umbracoContext) { if (content == null) throw new ArgumentNullException(nameof(content)); if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); var urls = new List(); if (content.HasPublishedVersion == false) { urls.Add(TextService.Localize("content/itemNotPublished")); return urls; } string url; var urlProvider = umbracoContext.UrlProvider; try { url = urlProvider.GetUrl(content.Id); } catch (Exception e) { Logger.Error("GetUrl exception.", e); url = "#ex"; } if (url == "#") { // document as a published version yet it's url is "#" => a parent must be // unpublished, walk up the tree until we find it, and report. var parent = content; do { parent = parent.ParentId > 0 ? parent.Parent(ContentService) : null; } while (parent != null && parent.Published); urls.Add(parent == null ? TextService.Localize("content/parentNotPublishedAnomaly") // oops - internal error : TextService.Localize("content/parentNotPublished", new[] { parent.Name })); } else if (url == "#ex") { urls.Add(TextService.Localize("content/getUrlException")); } else { // test for collisions var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute); if (uri.IsAbsoluteUri == false) uri = uri.MakeAbsolute(UmbracoContext.Current.CleanedUmbracoUrl); var r = Core.Composing.Current.Container.GetInstance(); // fixme inject or ? var pcr = r.CreateRequest(UmbracoContext.Current, uri); r.TryRouteRequest(pcr); if (pcr.HasPublishedContent == false) { urls.Add(TextService.Localize("content/routeError", new[] { "(error)" })); } else if (pcr.PublishedContent.Id != content.Id) { var o = pcr.PublishedContent; string s; if (o == null) { s = "(unknown)"; } else { var l = new List(); while (o != null) { l.Add(o.Name); o = o.Parent; } l.Reverse(); s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")"; } urls.Add(TextService.Localize("content/routeError", s)); } else { urls.Add(url); urls.AddRange(urlProvider.GetOtherUrls(content.Id)); } } return urls; } } }