diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs index 304066196d..04a33fc0bc 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs @@ -93,16 +93,6 @@ namespace Umbraco.Core.Models.PublishedContent /// DateTime UpdateDate { get; } - /// - /// Gets the url of the content item. - /// - /// - /// The value of this property is contextual. It depends on the 'current' request uri, - /// if any. In addition, when the content type is multi-lingual, this is the url for the - /// 'current' culture. Otherwise, it is the invariant url. - /// - string Url { get; } - /// /// Gets the url of the content item. /// @@ -111,7 +101,7 @@ namespace Umbraco.Core.Models.PublishedContent /// if any. In addition, when the content type is multi-lingual, this is the url for the /// specified culture. Otherwise, it is the invariant url. /// - string GetUrl(string culture = null); + string Url(string culture = null, UrlMode mode = UrlMode.Auto); /// /// Gets culture infos for a culture. diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs index 16732840ea..ee7ed31d1d 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs @@ -94,10 +94,7 @@ namespace Umbraco.Core.Models.PublishedContent public virtual DateTime UpdateDate => _content.UpdateDate; /// - public virtual string Url => _content.Url; - - /// - public virtual string GetUrl(string culture = null) => _content.GetUrl(culture); + public virtual string Url(string culture = null, UrlMode mode = UrlMode.Auto) => _content.Url(culture, mode); /// public PublishedCultureInfo GetCulture(string culture = null) => _content.GetCulture(culture); diff --git a/src/Umbraco.Web/Routing/UrlProviderMode.cs b/src/Umbraco.Core/Models/PublishedContent/UrlMode.cs similarity index 63% rename from src/Umbraco.Web/Routing/UrlProviderMode.cs rename to src/Umbraco.Core/Models/PublishedContent/UrlMode.cs index ac29aed3fb..f19f93bec1 100644 --- a/src/Umbraco.Web/Routing/UrlProviderMode.cs +++ b/src/Umbraco.Core/Models/PublishedContent/UrlMode.cs @@ -1,13 +1,9 @@ -namespace Umbraco.Web.Routing +namespace Umbraco.Core.Models.PublishedContent { /// - /// Specifies the type of urls that the url provider should produce, Auto is the default + /// Specifies the type of urls that the url provider should produce, Auto is the default. /// - /// - /// The Relative option can lead to invalid results when combined with hostnames, but it is the only way to reproduce - /// the true, pre-4.10, always-relative behavior of Umbraco. - /// - public enum UrlProviderMode + public enum UrlMode { /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 20cc089d1d..d0936fd579 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -223,6 +223,7 @@ + diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index 7d1ef25dcf..69eca7ef88 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -186,8 +186,7 @@ namespace Umbraco.Tests.PublishedContent private readonly Dictionary _names = new Dictionary(); private readonly Dictionary _urlSegments = new Dictionary(); - public string Url { get; set; } - public string GetUrl(string culture = null) => throw new NotSupportedException(); + public string Url(string culture = null, UrlMode mode = UrlMode.Auto) => default; public PublishedItemType ItemType { get; set; } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs index bf84413fae..f978c8501b 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs @@ -124,7 +124,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 0, Path = "/1", Level = 1, - Url = "/content-1", ParentId = -1, ChildIds = new[] { 2 }, Properties = new Collection @@ -134,6 +133,7 @@ namespace Umbraco.Tests.PublishedContent }; item1.SetName("Content 1"); item1.SetUrlSegment("content-1"); + item1.SetUrl("/content-1"); var item2 = new SolidPublishedContent(contentType1) { @@ -141,7 +141,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 0, Path = "/1/2", Level = 2, - Url = "/content-1/content-2", ParentId = 1, ChildIds = new int[] { 3 }, Properties = new Collection @@ -151,6 +150,7 @@ namespace Umbraco.Tests.PublishedContent }; item2.SetName("Content 2"); item2.SetUrlSegment("content-2"); + item2.SetUrl("/content-1/content-2"); var prop4 = new SolidPublishedPropertyWithLanguageVariants { @@ -166,7 +166,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 0, Path = "/1/2/3", Level = 3, - Url = "/content-1/content-2/content-3", ParentId = 2, ChildIds = new int[] { }, Properties = new Collection @@ -176,6 +175,7 @@ namespace Umbraco.Tests.PublishedContent }; item3.SetName("Content 3"); item3.SetUrlSegment("content-3"); + item3.SetUrl("/content-1/content-2/content-3"); item1.Children = new List { item2 }; item2.Parent = item1; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 9f9f3b8d41..378671b81b 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -31,7 +31,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 0, Path = "/1", Level = 1, - Url = "/content-1", ParentId = -1, ChildIds = new int[] { }, Properties = new Collection @@ -47,6 +46,7 @@ namespace Umbraco.Tests.PublishedContent }; content.SetName("Content 1"); content.SetUrlSegment("content-1"); + content.SetUrl("/content-1"); cache.Add(content); content = new SolidPublishedContent(contentType2) @@ -55,7 +55,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 1, Path = "/2", Level = 1, - Url = "/content-2", ParentId = -1, ChildIds = new int[] { }, Properties = new Collection @@ -71,6 +70,7 @@ namespace Umbraco.Tests.PublishedContent }; content.SetName("Content 2"); content.SetUrlSegment("content-2"); + content.SetUrl("/content-2"); cache.Add(content); content = new SolidPublishedContent(contentType2Sub) @@ -79,7 +79,6 @@ namespace Umbraco.Tests.PublishedContent SortOrder = 2, Path = "/3", Level = 1, - Url = "/content-2sub", ParentId = -1, ChildIds = new int[] { }, Properties = new Collection @@ -95,6 +94,7 @@ namespace Umbraco.Tests.PublishedContent }; content.SetName("Content 2Sub"); content.SetUrlSegment("content-2sub"); + content.SetUrl("/content-2sub"); cache.Add(content); } diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs index e1c8cda3a9..91fd1efb92 100644 --- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs +++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs @@ -157,6 +157,7 @@ namespace Umbraco.Tests.PublishedContent { private readonly Dictionary _names = new Dictionary(); private readonly Dictionary _urlSegments = new Dictionary(); + private readonly Dictionary _urls = new Dictionary(); #region Constructor @@ -195,8 +196,8 @@ namespace Umbraco.Tests.PublishedContent public DateTime UpdateDate { get; set; } public Guid Version { get; set; } public int Level { get; set; } - public string Url { get; set; } - public string GetUrl(string culture = null) => throw new NotSupportedException(); + public string Url(string culture = null, UrlMode mode = UrlMode.Auto) => _urls.TryGetValue(culture ?? "", out var url) ? url : null; + public void SetUrl(string url, string culture = null) => _urls[culture ?? ""] = url; public PublishedItemType ItemType { get { return PublishedItemType.Content; } } public bool IsDraft(string culture = null) => false; diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs index 236c198b3a..38ef983120 100644 --- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs @@ -314,7 +314,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual("/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); - umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; + umbracoContext.UrlProvider.Mode = UrlMode.Absolute; Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", umbracoContext.UrlProvider.GetUrl(1177)); } @@ -335,7 +335,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999)); - umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; + umbracoContext.UrlProvider.Mode = UrlMode.Absolute; Assert.AreEqual("#", umbracoContext.UrlProvider.GetUrl(999999)); } diff --git a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs index c01ee83d6a..5a20d4da31 100644 --- a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Tests.LegacyXmlPublishedCache; using Umbraco.Tests.TestHelpers; @@ -359,7 +360,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual("/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", umbracoContext.UrlProvider.GetUrl(100311)); - umbracoContext.UrlProvider.Mode = UrlProviderMode.Absolute; + umbracoContext.UrlProvider.Mode = UrlMode.Absolute; Assert.AreEqual("http://domain1.com/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111)); Assert.AreEqual("http://domain3.com/en/1003-1-1/", umbracoContext.UrlProvider.GetUrl(100311)); diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs index e07ae576e6..9f57109329 100644 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs @@ -194,7 +194,7 @@ namespace Umbraco.Tests.Runtimes Assert.IsTrue(pcontent.IsDraft()); // no published url - Assert.AreEqual("#", pcontent.GetUrl()); + Assert.AreEqual("#", pcontent.Url()); // now publish the document + make some unpublished changes contentService.SaveAndPublish(content); @@ -208,7 +208,7 @@ namespace Umbraco.Tests.Runtimes Assert.IsFalse(pcontent.IsDraft()); // but the url is the published one - no draft url - Assert.AreEqual("/test/", pcontent.GetUrl()); + Assert.AreEqual("/test/", pcontent.Url()); // and also an updated draft document pcontent = umbracoContext.ContentCache.GetById(true, content.Id); @@ -217,7 +217,7 @@ namespace Umbraco.Tests.Runtimes Assert.IsTrue(pcontent.IsDraft()); // and the published document has a url - Assert.AreEqual("/test/", pcontent.GetUrl()); + Assert.AreEqual("/test/", pcontent.Url()); umbracoContextReference.Dispose(); mainDom.Stop(); diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs index c6bbebf550..cf2b3b843f 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs @@ -146,7 +146,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting umbracoContextAccessor.UmbracoContext = umbCtx; var urlHelper = new Mock(); - urlHelper.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + urlHelper.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(UrlInfo.Url("/hello/world/1234")); var membershipHelper = new MembershipHelper(umbCtx.HttpContext, Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of()); diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs index d621197bf8..4262851fc9 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs @@ -49,8 +49,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs public DateTime UpdateDate { get; set; } public Guid Version { get; set; } public int Level { get; set; } - public string Url { get; set; } - public string GetUrl(string culture = null) => throw new NotSupportedException(); + public string Url(string culture = null, UrlMode mode = UrlMode.Auto) => throw new NotSupportedException(); public PublishedItemType ItemType => ContentType.ItemType; public bool IsDraft(string culture = null) => false; public bool IsPublished(string culture = null) => true; diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index 75e9cd60cb..ee938cd027 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Services; @@ -145,7 +146,7 @@ namespace Umbraco.Tests.TestHelpers var umbracoSettingsMock = new Mock(); var webRoutingSectionMock = new Mock(); - webRoutingSectionMock.Setup(x => x.UrlProviderMode).Returns(UrlProviderMode.Auto.ToString()); + webRoutingSectionMock.Setup(x => x.UrlProviderMode).Returns(UrlMode.Auto.ToString()); umbracoSettingsMock.Setup(x => x.WebRouting).Returns(webRoutingSectionMock.Object); return umbracoSettingsMock.Object; } diff --git a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs index 57381eb287..f0e31226e2 100644 --- a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs +++ b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs @@ -76,7 +76,7 @@ namespace Umbraco.Tests.Testing.TestingTests var umbracoContext = TestObjects.GetUmbracoContextMock(); var urlProviderMock = new Mock(); - urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(UrlInfo.Url("/hello/world/1234")); var urlProvider = urlProviderMock.Object; diff --git a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs index 5e9208faf9..c868914347 100644 --- a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs +++ b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs @@ -80,8 +80,8 @@ namespace Umbraco.Tests.Web //setup a mock url provider which we'll use fo rtesting var testUrlProvider = new Mock(); testUrlProvider - .Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns((UmbracoContext umbCtx, IPublishedContent content, UrlProviderMode mode, string culture, Uri url) => UrlInfo.Url("/my-test-url")); + .Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((UmbracoContext umbCtx, IPublishedContent content, UrlMode mode, string culture, Uri url) => UrlInfo.Url("/my-test-url")); var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); diff --git a/src/Umbraco.Web/Controllers/UmbLoginController.cs b/src/Umbraco.Web/Controllers/UmbLoginController.cs index 2980b4a4c0..02130da8b5 100644 --- a/src/Umbraco.Web/Controllers/UmbLoginController.cs +++ b/src/Umbraco.Web/Controllers/UmbLoginController.cs @@ -45,7 +45,7 @@ namespace Umbraco.Web.Controllers // if it's not a local url we'll redirect to the root of the current site return Redirect(Url.IsLocalUrl(model.RedirectUrl) ? model.RedirectUrl - : CurrentPage.AncestorOrSelf(1).Url); + : CurrentPage.AncestorOrSelf(1).Url()); } //redirect to current page by default diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index 977cd6fdc9..1fafefdcc5 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -277,9 +277,7 @@ namespace Umbraco.Web.Macros public int Level => _inner.Level; - public string Url => throw new NotImplementedException(); - - public string GetUrl(string culture = null) => throw new NotSupportedException(); + public string Url(string culture = null, UrlMode mode = UrlMode.Auto) => throw new NotSupportedException(); public PublishedItemType ItemType => PublishedItemType.Content; diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs index f93a6d08c4..e46bb8fddd 100644 --- a/src/Umbraco.Web/Models/PublishedContentBase.cs +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -76,15 +76,12 @@ namespace Umbraco.Web.Models /// public abstract DateTime UpdateDate { get; } - /// - public virtual string Url => GetUrl(); - /// /// /// The url of documents are computed by the document url providers. The url of medias are, at the moment, /// computed here from the 'umbracoFile' property -- but we should move to media url providers at some point. /// - public virtual string GetUrl(string culture = null) // TODO: consider .GetCulture("fr-FR").Url + public virtual string Url(string culture = null, UrlMode mode = UrlMode.Auto) { switch (ItemType) { @@ -96,9 +93,12 @@ namespace Umbraco.Web.Models if (umbracoContext.UrlProvider == null) throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.UrlProvider is null."); - return umbracoContext.UrlProvider.GetUrl(this, culture); + return umbracoContext.UrlProvider.GetUrl(this, mode, culture); case PublishedItemType.Media: + if (mode == UrlMode.Absolute) + throw new NotSupportedException("Absolute urls are not supported for media items."); + var prop = GetProperty(Constants.Conventions.Media.File); if (prop?.GetValue() == null) { diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs index 1cb590d43c..ac0fb375c7 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -82,7 +82,7 @@ namespace Umbraco.Web.PropertyEditors icon = documentEntity.ContentTypeIcon; published = culture == null ? documentEntity.Published : documentEntity.PublishedCultures.Contains(culture); udi = new GuidUdi(Constants.UdiEntityType.Document, documentEntity.Key); - url = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(entity.Key)?.Url ?? "#"; + url = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(entity.Key)?.Url() ?? "#"; trashed = documentEntity.Trashed; } else if(entity is IContentEntitySlim contentEntity) @@ -91,7 +91,7 @@ namespace Umbraco.Web.PropertyEditors isMedia = true; published = !contentEntity.Trashed; udi = new GuidUdi(Constants.UdiEntityType.Media, contentEntity.Key); - url = _publishedSnapshotAccessor.PublishedSnapshot.Media.GetById(entity.Key)?.Url ?? "#"; + url = _publishedSnapshotAccessor.PublishedSnapshot.Media.GetById(entity.Key)?.Url() ?? "#"; trashed = contentEntity.Trashed; } else diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiUrlPickerValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiUrlPickerValueConverter.cs index 87ab5b8ff9..8e9ee9d6f8 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiUrlPickerValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiUrlPickerValueConverter.cs @@ -69,7 +69,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters { continue; } - url = content.Url; + url = content.Url(); } links.Add( diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 2495415834..7776a7c8ac 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -24,65 +24,6 @@ namespace Umbraco.Web private static IPublishedValueFallback PublishedValueFallback => Current.PublishedValueFallback; private static IPublishedSnapshot PublishedSnapshot => Current.PublishedSnapshot; - #region Urls - - /// - /// Gets the url for the content. - /// - /// The content. - /// The url for the content. - /// Better use the Url property but that method is here to complement UrlAbsolute(). - public static string Url(this IPublishedContent content) - { - return content.Url; - } - - /// - /// Gets the absolute url for the content. - /// - /// The content. - /// The absolute url for the content. - public static string UrlAbsolute(this IPublishedContent content) - { - // adapted from PublishedContentBase.Url - switch (content.ItemType) - { - case PublishedItemType.Content: - if (Current.UmbracoContext == null) - throw new InvalidOperationException("Cannot resolve a Url for a content item when Current.UmbracoContext is null."); - if (Current.UmbracoContext.UrlProvider == null) - throw new InvalidOperationException("Cannot resolve a Url for a content item when Current.UmbracoContext.UrlProvider is null."); - return Current.UmbracoContext.UrlProvider.GetUrl(content.Id, true); - case PublishedItemType.Media: - throw new NotSupportedException("AbsoluteUrl is not supported for media types."); - default: - throw new ArgumentOutOfRangeException(); - } - } - - public static bool IsAllowedTemplate(this IPublishedContent content, int templateId) - { - if (Current.Configs.Settings().WebRouting.DisableAlternativeTemplates) - return content.TemplateId == templateId; - - if (content.TemplateId == templateId || !Current.Configs.Settings().WebRouting.ValidateAlternativeTemplates) - return true; - - var publishedContentContentType = Current.Services.ContentTypeService.Get(content.ContentType.Id); - if (publishedContentContentType == null) - throw new NullReferenceException("No content type returned for published content (contentType='" + content.ContentType.Id + "')"); - - return publishedContentContentType.IsAllowedTemplate(templateId); - - } - public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) - { - var template = Current.Services.FileService.GetTemplate(templateAlias); - return template != null && content.IsAllowedTemplate(template.Id); - } - - #endregion - #region IsComposedOf /// @@ -116,6 +57,27 @@ namespace Umbraco.Web return template == null ? string.Empty : template.Alias; } + public static bool IsAllowedTemplate(this IPublishedContent content, int templateId) + { + if (Current.Configs.Settings().WebRouting.DisableAlternativeTemplates) + return content.TemplateId == templateId; + + if (content.TemplateId == templateId || !Current.Configs.Settings().WebRouting.ValidateAlternativeTemplates) + return true; + + var publishedContentContentType = Current.Services.ContentTypeService.Get(content.ContentType.Id); + if (publishedContentContentType == null) + throw new NullReferenceException("No content type returned for published content (contentType='" + content.ContentType.Id + "')"); + + return publishedContentContentType.IsAllowedTemplate(templateId); + + } + public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) + { + var template = Current.Services.FileService.GetTemplate(templateAlias); + return template != null && content.IsAllowedTemplate(template.Id); + } + #endregion #region HasValue, Value, Value @@ -1059,7 +1021,7 @@ namespace Umbraco.Web { "UpdateDate", n.UpdateDate }, { "CreatorName", n.CreatorName }, { "WriterName", n.WriterName }, - { "Url", n.Url } + { "Url", n.Url() } }; var userVals = new Dictionary(); diff --git a/src/Umbraco.Web/Routing/AliasUrlProvider.cs b/src/Umbraco.Web/Routing/AliasUrlProvider.cs index 4c879e931f..bbe3a9db8c 100644 --- a/src/Umbraco.Web/Routing/AliasUrlProvider.cs +++ b/src/Umbraco.Web/Routing/AliasUrlProvider.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web.Routing #region GetUrl /// - public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current) + public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { return null; // we have nothing to say } diff --git a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs index f20aa95c0d..eae2b57378 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs @@ -45,7 +45,7 @@ namespace Umbraco.Web.Routing } var content = frequest.UmbracoContext.ContentCache.GetById(redirectUrl.ContentId); - var url = content == null ? "#" : content.GetUrl(redirectUrl.Culture); + var url = content == null ? "#" : content.Url(redirectUrl.Culture); if (url.StartsWith("#")) { _logger.Debug("Route {Route} matches content {ContentId} which has no url.", route, redirectUrl.ContentId); diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index 9e13d3b9c1..98ba743fe5 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -29,7 +29,7 @@ namespace Umbraco.Web.Routing #region GetUrl /// - public virtual UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current) + public virtual UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { if (!current.IsAbsoluteUri) throw new ArgumentException("Current url must be absolute.", nameof(current)); @@ -39,7 +39,7 @@ namespace Umbraco.Web.Routing return GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture); } - internal UrlInfo GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture) + internal UrlInfo GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlMode mode, string culture) { if (string.IsNullOrWhiteSpace(route)) { @@ -121,7 +121,7 @@ namespace Umbraco.Web.Routing #region Utilities - Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode) + Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlMode mode) { Uri uri; @@ -130,15 +130,15 @@ namespace Umbraco.Web.Routing if (domainUri == null) // no domain was found { if (current == null) - mode = UrlProviderMode.Relative; // best we can do + mode = UrlMode.Relative; // best we can do switch (mode) { - case UrlProviderMode.Absolute: + case UrlMode.Absolute: uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path); break; - case UrlProviderMode.Relative: - case UrlProviderMode.Auto: + case UrlMode.Relative: + case UrlMode.Auto: uri = new Uri(path, UriKind.Relative); break; default: @@ -147,21 +147,21 @@ namespace Umbraco.Web.Routing } else // a domain was found { - if (mode == UrlProviderMode.Auto) + if (mode == UrlMode.Auto) { //this check is a little tricky, we can't just compare domains if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) - mode = UrlProviderMode.Relative; + mode = UrlMode.Relative; else - mode = UrlProviderMode.Absolute; + mode = UrlMode.Absolute; } switch (mode) { - case UrlProviderMode.Absolute: + case UrlMode.Absolute: uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); break; - case UrlProviderMode.Relative: + case UrlMode.Relative: uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); break; default: diff --git a/src/Umbraco.Web/Routing/IUrlProvider.cs b/src/Umbraco.Web/Routing/IUrlProvider.cs index 55d39880d6..854363f110 100644 --- a/src/Umbraco.Web/Routing/IUrlProvider.cs +++ b/src/Umbraco.Web/Routing/IUrlProvider.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a url, it should return null. /// - UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current); + UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current); /// /// Gets the other urls of a published content. diff --git a/src/Umbraco.Web/Routing/UrlProvider.cs b/src/Umbraco.Web/Routing/UrlProvider.cs index 0662d46f49..3e07c8020a 100644 --- a/src/Umbraco.Web/Routing/UrlProvider.cs +++ b/src/Umbraco.Web/Routing/UrlProvider.cs @@ -31,10 +31,10 @@ namespace Umbraco.Web.Routing _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); _urlProviders = urlProviders; _variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); - var provider = UrlProviderMode.Auto; + var provider = UrlMode.Auto; Mode = provider; - if (Enum.TryParse(routingSettings.UrlProviderMode, out provider)) + if (Enum.TryParse(routingSettings.UrlProviderMode, out provider)) { Mode = provider; } @@ -47,7 +47,7 @@ namespace Umbraco.Web.Routing /// The list of url providers. /// The current variation accessor. /// An optional provider mode. - public UrlProvider(UmbracoContext umbracoContext, IEnumerable urlProviders, IVariationContextAccessor variationContextAccessor, UrlProviderMode mode = UrlProviderMode.Auto) + public UrlProvider(UmbracoContext umbracoContext, IEnumerable urlProviders, IVariationContextAccessor variationContextAccessor, UrlMode mode = UrlMode.Auto) { _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); _urlProviders = urlProviders; @@ -63,13 +63,13 @@ namespace Umbraco.Web.Routing /// /// Gets or sets the provider url mode. /// - public UrlProviderMode Mode { get; set; } + public UrlMode Mode { get; set; } #endregion #region GetUrl - private UrlProviderMode GetMode(bool absolute) => absolute ? UrlProviderMode.Absolute : Mode; + private UrlMode GetMode(bool absolute) => absolute ? UrlMode.Absolute : Mode; private IPublishedContent GetDocument(int id) => _umbracoContext.ContentCache.GetById(id); private IPublishedContent GetDocument(Guid id) => _umbracoContext.ContentCache.GetById(id); @@ -131,7 +131,7 @@ namespace Umbraco.Web.Routing /// A culture. /// The current absolute url. /// The url for the published content. - public string GetUrl(Guid id, UrlProviderMode mode, string culture = null, Uri current = null) + public string GetUrl(Guid id, UrlMode mode, string culture = null, Uri current = null) => GetUrl(GetDocument(id), mode, culture, current); /// @@ -167,7 +167,7 @@ namespace Umbraco.Web.Routing /// A culture. /// The current absolute url. /// The url for the published content. - public string GetUrl(int id, UrlProviderMode mode, string culture = null, Uri current = null) + public string GetUrl(int id, UrlMode mode, string culture = null, Uri current = null) => GetUrl(GetDocument(id), mode, culture, current); /// @@ -184,7 +184,7 @@ namespace Umbraco.Web.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a url, it returns "#". /// - public string GetUrl(IPublishedContent content, UrlProviderMode mode, string culture = null, Uri current = null) + public string GetUrl(IPublishedContent content, UrlMode mode, string culture = null, Uri current = null) { if (content == null || content.ItemType == PublishedItemType.Element) return "#"; diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index 6c979e9a95..0be392c6dd 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -158,7 +158,7 @@ namespace Umbraco.Web.Templates return match.Value; } - var url = media.Url; + var url = media.Url(); return $"{match.Groups[1].Value}{url}{match.Groups[3].Value}{udi}{match.Groups[5].Value}"; }); } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index b3cab3b2cb..42a1a766e5 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1017,7 +1017,6 @@ - diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index d6df5480cd..a39535ba6e 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -208,8 +208,6 @@ namespace Umbraco.Web #region Urls - // fixme do something with these - /// /// Gets the url of a content identified by its identifier. /// @@ -239,7 +237,7 @@ namespace Umbraco.Web /// The mode. /// /// The url for the content. - public string Url(int contentId, UrlProviderMode mode, string culture = null) + public string Url(int contentId, UrlMode mode, string culture = null) { return UrlProvider.GetUrl(contentId, mode, culture); } @@ -251,7 +249,7 @@ namespace Umbraco.Web /// The mode. /// /// The url for the content. - public string Url(Guid contentId, UrlProviderMode mode, string culture = null) + public string Url(Guid contentId, UrlMode mode, string culture = null) { return UrlProvider.GetUrl(contentId, mode, culture); } @@ -262,6 +260,7 @@ namespace Umbraco.Web /// The content identifier. /// /// The absolute url for the content. + [Obsolete("Use the Url() method with UrlMode.Absolute.")] public string UrlAbsolute(int contentId, string culture = null) { return UrlProvider.GetUrl(contentId, true, culture); @@ -273,6 +272,7 @@ namespace Umbraco.Web /// The content identifier. /// /// The absolute url for the content. + [Obsolete("Use the Url() method with UrlMode.Absolute.")] public string UrlAbsolute(Guid contentId, string culture = null) { return UrlProvider.GetUrl(contentId, true, culture); diff --git a/src/Umbraco.Web/UrlHelperRenderExtensions.cs b/src/Umbraco.Web/UrlHelperRenderExtensions.cs index 6f7fbacf7a..8fe0524209 100644 --- a/src/Umbraco.Web/UrlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/UrlHelperRenderExtensions.cs @@ -385,7 +385,7 @@ namespace Umbraco.Web if (urlHelper.RequestContext.HttpContext.Request.Url != null) { var requestUrl = urlHelper.RequestContext.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority); - return string.Format("{0}{1}", requestUrl, mediaItem.Url); + return string.Format("{0}{1}", requestUrl, mediaItem.Url()); } return null; }