diff --git a/src/Umbraco.Abstractions/PublishedContentExtensions.cs b/src/Umbraco.Abstractions/PublishedContentExtensions.cs index 6132659977..84ee8c314b 100644 --- a/src/Umbraco.Abstractions/PublishedContentExtensions.cs +++ b/src/Umbraco.Abstractions/PublishedContentExtensions.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Composing; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web; @@ -146,6 +148,14 @@ namespace Umbraco.Core return template == null ? string.Empty : template.Alias; } + public static bool IsAllowedTemplate(this IPublishedContent content, IContentTypeService contentTypeService, + IUmbracoSettingsSection umbracoSettingsSection, int templateId) + { + return content.IsAllowedTemplate(contentTypeService, + umbracoSettingsSection.WebRouting.DisableAlternativeTemplates, + umbracoSettingsSection.WebRouting.ValidateAlternativeTemplates, templateId); + } + public static bool IsAllowedTemplate(this IPublishedContent content, IContentTypeService contentTypeService, bool disableAlternativeTemplates, bool validateAlternativeTemplates, int templateId) { if (disableAlternativeTemplates) diff --git a/src/Umbraco.Web/Routing/AliasUrlProvider.cs b/src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs similarity index 84% rename from src/Umbraco.Web/Routing/AliasUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs index 4c5d108698..c9cc3d5156 100644 --- a/src/Umbraco.Web/Routing/AliasUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/AliasUrlProvider.cs @@ -17,12 +17,16 @@ namespace Umbraco.Web.Routing private readonly IRequestHandlerSection _requestConfig; private readonly ISiteDomainHelper _siteDomainHelper; private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly UriUtility _uriUtility; + private readonly IPublishedValueFallback _publishedValueFallback; - public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ISiteDomainHelper siteDomainHelper, IUmbracoContextAccessor umbracoContextAccessor) + public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ISiteDomainHelper siteDomainHelper, UriUtility uriUtility, IPublishedValueFallback publishedValueFallback, IUmbracoContextAccessor umbracoContextAccessor) { _globalSettings = globalSettings; _requestConfig = requestConfig; _siteDomainHelper = siteDomainHelper; + _uriUtility = uriUtility; + _publishedValueFallback = publishedValueFallback; _umbracoContextAccessor = umbracoContextAccessor; } @@ -86,7 +90,7 @@ namespace Umbraco.Web.Routing if (varies) yield break; - var umbracoUrlName = node.Value(Constants.Conventions.Content.UrlAlias); + var umbracoUrlName = node.Value(_publishedValueFallback, Constants.Conventions.Content.UrlAlias); var aliases = umbracoUrlName?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (aliases == null || aliases.Any() == false) @@ -96,7 +100,7 @@ namespace Umbraco.Web.Routing { var path = "/" + alias; var uri = new Uri(path, UriKind.Relative); - yield return UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString()); + yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString()); } } else @@ -111,8 +115,8 @@ namespace Umbraco.Web.Routing if (varies && !node.HasCulture(domainUri.Culture.Name)) continue; var umbracoUrlName = varies - ? node.Value(Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name) - : node.Value(Constants.Conventions.Content.UrlAlias); + ? node.Value(_publishedValueFallback,Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name) + : node.Value(_publishedValueFallback, Constants.Conventions.Content.UrlAlias); var aliases = umbracoUrlName?.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries); @@ -123,7 +127,7 @@ namespace Umbraco.Web.Routing { var path = "/" + alias; var uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); - yield return UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString(), domainUri.Culture.Name); + yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString(), domainUri.Culture.Name); } } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs similarity index 91% rename from src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs index 9a8c1d2729..5b3e0a5d99 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByRedirectUrl.cs @@ -17,11 +17,13 @@ namespace Umbraco.Web.Routing { private readonly IRedirectUrlService _redirectUrlService; private readonly ILogger _logger; + private readonly IPublishedUrlProvider _publishedUrlProvider; - public ContentFinderByRedirectUrl(IRedirectUrlService redirectUrlService, ILogger logger) + public ContentFinderByRedirectUrl(IRedirectUrlService redirectUrlService, ILogger logger, IPublishedUrlProvider publishedUrlProvider) { _redirectUrlService = redirectUrlService; _logger = logger; + _publishedUrlProvider = publishedUrlProvider; } /// @@ -45,7 +47,7 @@ namespace Umbraco.Web.Routing } var content = frequest.UmbracoContext.Content.GetById(redirectUrl.ContentId); - var url = content == null ? "#" : content.Url(redirectUrl.Culture); + var url = content == null ? "#" : content.Url(_publishedUrlProvider, 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/ContentFinderByUrl.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrl.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderByUrl.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrl.cs diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs similarity index 81% rename from src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs index ae435eff87..6bc1b329ed 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAlias.cs @@ -18,10 +18,14 @@ namespace Umbraco.Web.Routing /// public class ContentFinderByUrlAlias : IContentFinder { + private readonly IPublishedValueFallback _publishedValueFallback; + private readonly IVariationContextAccessor _variationContextAccessor; protected ILogger Logger { get; } - public ContentFinderByUrlAlias(ILogger logger) + public ContentFinderByUrlAlias(ILogger logger, IPublishedValueFallback publishedValueFallback, IVariationContextAccessor variationContextAccessor) { + _publishedValueFallback = publishedValueFallback; + _variationContextAccessor = variationContextAccessor; Logger = logger; } @@ -51,7 +55,7 @@ namespace Umbraco.Web.Routing return node != null; } - private static IPublishedContent FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string culture, string alias) + private IPublishedContent FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string culture, string alias) { if (alias == null) throw new ArgumentNullException(nameof(alias)); @@ -84,11 +88,11 @@ namespace Umbraco.Web.Routing if (varies) { if (!c.HasCulture(culture)) return false; - v = c.Value(propertyAlias, culture); + v = c.Value(_publishedValueFallback, propertyAlias, culture); } else { - v = c.Value(propertyAlias); + v = c.Value(_publishedValueFallback, propertyAlias); } if (string.IsNullOrWhiteSpace(v)) return false; v = "," + v.Replace(" ", "") + ","; @@ -101,12 +105,12 @@ namespace Umbraco.Web.Routing if (rootNodeId > 0) { var rootNode = cache.GetById(rootNodeId); - return rootNode?.Descendants().FirstOrDefault(x => IsMatch(x, test1, test2)); + return rootNode?.Descendants(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); } foreach (var rootContent in cache.GetAtRoot()) { - var c = rootContent.DescendantsOrSelf().FirstOrDefault(x => IsMatch(x, test1, test2)); + var c = rootContent.DescendantsOrSelf(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); if (c != null) return c; } diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs similarity index 87% rename from src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs index 84529dfaa1..933ab47150 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs +++ b/src/Umbraco.Abstractions/Routing/ContentFinderByUrlAndTemplate.cs @@ -1,9 +1,7 @@ using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core; -using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Composing; using Umbraco.Core.Services; namespace Umbraco.Web.Routing @@ -19,11 +17,15 @@ namespace Umbraco.Web.Routing public class ContentFinderByUrlAndTemplate : ContentFinderByUrl { private readonly IFileService _fileService; + private readonly IUmbracoSettingsSection _umbracoSettingsSection; + private readonly IContentTypeService _contentTypeService; - public ContentFinderByUrlAndTemplate(ILogger logger, IFileService fileService) + public ContentFinderByUrlAndTemplate(ILogger logger, IFileService fileService, IUmbracoSettingsSection umbracoSettingsSection, IContentTypeService contentTypeService) : base(logger) { _fileService = fileService; + _umbracoSettingsSection = umbracoSettingsSection; + _contentTypeService = contentTypeService; } /// @@ -73,7 +75,7 @@ namespace Umbraco.Web.Routing } // IsAllowedTemplate deals both with DisableAlternativeTemplates and ValidateAlternativeTemplates settings - if (!node.IsAllowedTemplate(template.Id)) + if (!node.IsAllowedTemplate(_contentTypeService, _umbracoSettingsSection, template.Id)) { Logger.Warn("Alternative template '{TemplateAlias}' is not allowed on node {NodeId}.", template.Alias, node.Id); frequest.PublishedContent = null; // clear diff --git a/src/Umbraco.Web/Routing/ContentFinderCollection.cs b/src/Umbraco.Abstractions/Routing/ContentFinderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderCollection.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderCollection.cs diff --git a/src/Umbraco.Web/Routing/ContentFinderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/ContentFinderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/ContentFinderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/ContentFinderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs b/src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs similarity index 92% rename from src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs index f2cc870eef..08ffb7b1ff 100644 --- a/src/Umbraco.Web/Routing/DefaultMediaUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/DefaultMediaUrlProvider.cs @@ -9,11 +9,13 @@ namespace Umbraco.Web.Routing /// public class DefaultMediaUrlProvider : IMediaUrlProvider { + private readonly UriUtility _uriUtility; private readonly Lazy _propertyEditors; - public DefaultMediaUrlProvider(Lazy propertyEditors) + public DefaultMediaUrlProvider(Lazy propertyEditors, UriUtility uriUtility) { _propertyEditors = propertyEditors ?? throw new ArgumentNullException(nameof(propertyEditors)); + _uriUtility = uriUtility; } /// @@ -69,7 +71,7 @@ namespace Umbraco.Web.Routing throw new ArgumentOutOfRangeException(nameof(mode)); } - return UriUtility.MediaUriFromUmbraco(uri); + return _uriUtility.MediaUriFromUmbraco(uri); } } } diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs similarity index 96% rename from src/Umbraco.Web/Routing/DefaultUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs index 40d7e116a8..81102810e8 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/DefaultUrlProvider.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; @@ -18,13 +17,15 @@ namespace Umbraco.Web.Routing private readonly IGlobalSettings _globalSettings; private readonly ISiteDomainHelper _siteDomainHelper; private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly UriUtility _uriUtility; - public DefaultUrlProvider(IRequestHandlerSection requestSettings, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, IUmbracoContextAccessor umbracoContextAccessor) + public DefaultUrlProvider(IRequestHandlerSection requestSettings, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, IUmbracoContextAccessor umbracoContextAccessor, UriUtility uriUtility) { _requestSettings = requestSettings; _logger = logger; _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; + _uriUtility = uriUtility; _umbracoContextAccessor = umbracoContextAccessor; } @@ -112,7 +113,7 @@ namespace Umbraco.Web.Routing var path = pos == 0 ? route : route.Substring(pos); var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path)); - uri = UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); + uri = _uriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); yield return UrlInfo.Url(uri.ToString(), culture); } } @@ -171,7 +172,7 @@ namespace Umbraco.Web.Routing // UriFromUmbraco will handle vdir // meaning it will add vdir into domain urls too! - return UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); + return _uriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings); } string CombinePaths(string path1, string path2) diff --git a/src/Umbraco.Web/Routing/EnsureRoutableOutcome.cs b/src/Umbraco.Abstractions/Routing/EnsureRoutableOutcome.cs similarity index 100% rename from src/Umbraco.Web/Routing/EnsureRoutableOutcome.cs rename to src/Umbraco.Abstractions/Routing/EnsureRoutableOutcome.cs diff --git a/src/Umbraco.Web/Routing/IContentFinder.cs b/src/Umbraco.Abstractions/Routing/IContentFinder.cs similarity index 100% rename from src/Umbraco.Web/Routing/IContentFinder.cs rename to src/Umbraco.Abstractions/Routing/IContentFinder.cs diff --git a/src/Umbraco.Web/Routing/IContentLastChanceFinder.cs b/src/Umbraco.Abstractions/Routing/IContentLastChanceFinder.cs similarity index 100% rename from src/Umbraco.Web/Routing/IContentLastChanceFinder.cs rename to src/Umbraco.Abstractions/Routing/IContentLastChanceFinder.cs diff --git a/src/Umbraco.Web/Routing/IMediaUrlProvider.cs b/src/Umbraco.Abstractions/Routing/IMediaUrlProvider.cs similarity index 100% rename from src/Umbraco.Web/Routing/IMediaUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/IMediaUrlProvider.cs diff --git a/src/Umbraco.Web/Routing/IPublishedRouter.cs b/src/Umbraco.Abstractions/Routing/IPublishedRouter.cs similarity index 100% rename from src/Umbraco.Web/Routing/IPublishedRouter.cs rename to src/Umbraco.Abstractions/Routing/IPublishedRouter.cs diff --git a/src/Umbraco.Web/Routing/IUrlProvider.cs b/src/Umbraco.Abstractions/Routing/IUrlProvider.cs similarity index 100% rename from src/Umbraco.Web/Routing/IUrlProvider.cs rename to src/Umbraco.Abstractions/Routing/IUrlProvider.cs diff --git a/src/Umbraco.Web/Routing/MediaUrlProviderCollection.cs b/src/Umbraco.Abstractions/Routing/MediaUrlProviderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/MediaUrlProviderCollection.cs rename to src/Umbraco.Abstractions/Routing/MediaUrlProviderCollection.cs diff --git a/src/Umbraco.Web/Routing/MediaUrlProviderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/MediaUrlProviderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/MediaUrlProviderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/MediaUrlProviderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/PublishedRequest.cs b/src/Umbraco.Abstractions/Routing/PublishedRequest.cs similarity index 99% rename from src/Umbraco.Web/Routing/PublishedRequest.cs rename to src/Umbraco.Abstractions/Routing/PublishedRequest.cs index 86bca12ef9..9b00e59deb 100644 --- a/src/Umbraco.Web/Routing/PublishedRequest.cs +++ b/src/Umbraco.Abstractions/Routing/PublishedRequest.cs @@ -2,12 +2,8 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Threading; -using System.Web; -using Umbraco.Core; -using Umbraco.Web.Composing; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Macros; using Umbraco.Core.Configuration.UmbracoSettings; namespace Umbraco.Web.Routing diff --git a/src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs b/src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs similarity index 79% rename from src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs rename to src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs index eea33f95fe..54ea98b3a4 100644 --- a/src/Umbraco.Web/Routing/RoutableAttemptEventArgs.cs +++ b/src/Umbraco.Abstractions/Routing/RoutableAttemptEventArgs.cs @@ -9,8 +9,8 @@ namespace Umbraco.Web.Routing { public EnsureRoutableOutcome Outcome { get; private set; } - public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, IUmbracoContext umbracoContext, HttpContextBase httpContext) - : base(umbracoContext, httpContext) + public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, IUmbracoContext umbracoContext) + : base(umbracoContext) { Outcome = reason; } diff --git a/src/Umbraco.Web/Routing/SiteDomainHelper.cs b/src/Umbraco.Abstractions/Routing/SiteDomainHelper.cs similarity index 100% rename from src/Umbraco.Web/Routing/SiteDomainHelper.cs rename to src/Umbraco.Abstractions/Routing/SiteDomainHelper.cs diff --git a/src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs b/src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs similarity index 76% rename from src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs rename to src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs index 56c9c9f07d..4430d9689f 100644 --- a/src/Umbraco.Web/Routing/UmbracoRequestEventArgs.cs +++ b/src/Umbraco.Abstractions/Routing/UmbracoRequestEventArgs.cs @@ -9,12 +9,10 @@ namespace Umbraco.Web.Routing public class UmbracoRequestEventArgs : EventArgs { public IUmbracoContext UmbracoContext { get; private set; } - public HttpContextBase HttpContext { get; private set; } - public UmbracoRequestEventArgs(IUmbracoContext umbracoContext, HttpContextBase httpContext) + public UmbracoRequestEventArgs(IUmbracoContext umbracoContext) { UmbracoContext = umbracoContext; - HttpContext = httpContext; } } } diff --git a/src/Umbraco.Web/UriUtility.cs b/src/Umbraco.Abstractions/Routing/UriUtility.cs similarity index 84% rename from src/Umbraco.Web/UriUtility.cs rename to src/Umbraco.Abstractions/Routing/UriUtility.cs index 6093d3e55a..11bb1dabfb 100644 --- a/src/Umbraco.Web/UriUtility.cs +++ b/src/Umbraco.Abstractions/Routing/UriUtility.cs @@ -4,21 +4,22 @@ using System.Web; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; namespace Umbraco.Web { - public static class UriUtility + public sealed class UriUtility { static string _appPath; static string _appPathPrefix; - static UriUtility() + public UriUtility(IHostingEnvironment hostingEnvironment) { - ResetAppDomainAppVirtualPath(); + ResetAppDomainAppVirtualPath(hostingEnvironment); } // internal for unit testing only - internal static void SetAppDomainAppVirtualPath(string appPath) + internal void SetAppDomainAppVirtualPath(string appPath) { _appPath = appPath ?? "/"; _appPathPrefix = _appPath; @@ -26,20 +27,20 @@ namespace Umbraco.Web _appPathPrefix = String.Empty; } - internal static void ResetAppDomainAppVirtualPath() + internal void ResetAppDomainAppVirtualPath(IHostingEnvironment hostingEnvironment) { - SetAppDomainAppVirtualPath(HttpRuntime.AppDomainAppVirtualPath); + SetAppDomainAppVirtualPath(hostingEnvironment.ApplicationVirtualPath); } // will be "/" or "/foo" - public static string AppPath => _appPath; + public string AppPath => _appPath; // will be "" or "/foo" - public static string AppPathPrefix => _appPathPrefix; + public string AppPathPrefix => _appPathPrefix; // adds the virtual directory if any // see also VirtualPathUtility.ToAbsolute - public static string ToAbsolute(string url) + public string ToAbsolute(string url) { //return ResolveUrl(url); url = url.TrimStart('~'); @@ -48,7 +49,7 @@ namespace Umbraco.Web // strips the virtual directory if any // see also VirtualPathUtility.ToAppRelative - public static string ToAppRelative(string virtualPath) + public string ToAppRelative(string virtualPath) { if (virtualPath.InvariantStartsWith(_appPathPrefix) && (virtualPath.Length == _appPathPrefix.Length || virtualPath[_appPathPrefix.Length] == '/')) @@ -60,7 +61,7 @@ namespace Umbraco.Web // maps an internal umbraco uri to a public uri // ie with virtual directory, .aspx if required... - public static Uri UriFromUmbraco(Uri uri, IGlobalSettings globalSettings, IRequestHandlerSection requestConfig) + public Uri UriFromUmbraco(Uri uri, IGlobalSettings globalSettings, IRequestHandlerSection requestConfig) { var path = uri.GetSafeAbsolutePath(); @@ -74,7 +75,7 @@ namespace Umbraco.Web // maps a media umbraco uri to a public uri // ie with virtual directory - that is all for media - public static Uri MediaUriFromUmbraco(Uri uri) + public Uri MediaUriFromUmbraco(Uri uri) { var path = uri.GetSafeAbsolutePath(); path = ToAbsolute(path); @@ -83,7 +84,7 @@ namespace Umbraco.Web // maps a public uri to an internal umbraco uri // ie no virtual directory, no .aspx, lowercase... - public static Uri UriToUmbraco(Uri uri) + public Uri UriToUmbraco(Uri uri) { // note: no need to decode uri here because we're returning a uri // so it will be re-encoded anyway @@ -120,7 +121,7 @@ namespace Umbraco.Web // ResolveUrl("page2.aspx") returns "/page2.aspx" // Page.ResolveUrl("page2.aspx") returns "/sub/page2.aspx" (relative...) // - public static string ResolveUrl(string relativeUrl) + public string ResolveUrl(string relativeUrl) { if (relativeUrl == null) throw new ArgumentNullException("relativeUrl"); @@ -182,21 +183,22 @@ namespace Umbraco.Web /// Returns an full url with the host, port, etc... /// /// An absolute path (i.e. starts with a '/' ) - /// + /// /// /// /// Based on http://stackoverflow.com/questions/3681052/get-absolute-url-from-relative-path-refactored-method /// - internal static Uri ToFullUrl(string absolutePath, HttpContextBase httpContext) + internal Uri ToFullUrl(string absolutePath, Uri curentRequestUrl) { - if (httpContext == null) throw new ArgumentNullException("httpContext"); if (string.IsNullOrEmpty(absolutePath)) - throw new ArgumentNullException("absolutePath"); + throw new ArgumentNullException(nameof(absolutePath)); if (!absolutePath.StartsWith("/")) throw new FormatException("The absolutePath specified does not start with a '/'"); - return new Uri(absolutePath, UriKind.Relative).MakeAbsolute(httpContext.Request.Url); + return new Uri(absolutePath, UriKind.Relative).MakeAbsolute(curentRequestUrl); } + + } } diff --git a/src/Umbraco.Web/Routing/UrlProvider.cs b/src/Umbraco.Abstractions/Routing/UrlProvider.cs similarity index 99% rename from src/Umbraco.Web/Routing/UrlProvider.cs rename to src/Umbraco.Abstractions/Routing/UrlProvider.cs index 18a4f09afb..80169e54e2 100644 --- a/src/Umbraco.Web/Routing/UrlProvider.cs +++ b/src/Umbraco.Abstractions/Routing/UrlProvider.cs @@ -4,7 +4,6 @@ using System.Linq; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.Routing { diff --git a/src/Umbraco.Web/Routing/UrlProviderCollection.cs b/src/Umbraco.Abstractions/Routing/UrlProviderCollection.cs similarity index 100% rename from src/Umbraco.Web/Routing/UrlProviderCollection.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderCollection.cs diff --git a/src/Umbraco.Web/Routing/UrlProviderCollectionBuilder.cs b/src/Umbraco.Abstractions/Routing/UrlProviderCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Web/Routing/UrlProviderCollectionBuilder.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderCollectionBuilder.cs diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs similarity index 95% rename from src/Umbraco.Web/Routing/UrlProviderExtensions.cs rename to src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs index b53676ca1d..a7f8a97c6d 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Abstractions/Routing/UrlProviderExtensions.cs @@ -26,6 +26,7 @@ namespace Umbraco.Web.Routing IContentService contentService, IVariationContextAccessor variationContextAccessor, ILogger logger, + UriUtility uriUtility, IPublishedUrlProvider publishedUrlProvider) { if (content == null) throw new ArgumentNullException(nameof(content)); @@ -36,6 +37,7 @@ namespace Umbraco.Web.Routing if (contentService == null) throw new ArgumentNullException(nameof(contentService)); if (logger == null) throw new ArgumentNullException(nameof(logger)); if (publishedUrlProvider == null) throw new ArgumentNullException(nameof(publishedUrlProvider)); + if (uriUtility == null) throw new ArgumentNullException(nameof(uriUtility)); if (variationContextAccessor == null) throw new ArgumentNullException(nameof(variationContextAccessor)); if (content.Published == false) @@ -61,7 +63,7 @@ namespace Umbraco.Web.Routing //get all URLs for all cultures //in a HashSet, so de-duplicates too - foreach (var cultureUrl in GetContentUrlsByCulture(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger, publishedUrlProvider)) + foreach (var cultureUrl in GetContentUrlsByCulture(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger, uriUtility, publishedUrlProvider)) { urls.Add(cultureUrl); } @@ -103,6 +105,7 @@ namespace Umbraco.Web.Routing ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, ILogger logger, + UriUtility uriUtility, IPublishedUrlProvider publishedUrlProvider) { foreach (var culture in cultures) @@ -138,7 +141,7 @@ namespace Umbraco.Web.Routing // got a url, deal with collisions, add url default: - if (DetectCollision(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, out var urlInfo)) // detect collisions, etc + if (DetectCollision(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, uriUtility, out var urlInfo)) // detect collisions, etc yield return urlInfo; else yield return UrlInfo.Url(url, culture); @@ -168,12 +171,12 @@ namespace Umbraco.Web.Routing return UrlInfo.Message(textService.Localize("content/parentCultureNotPublished", new[] {parent.Name}), culture); } - private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, out UrlInfo urlInfo) + private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, UriUtility uriUtility, out UrlInfo urlInfo) { // test for collisions on the 'main' url var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute); if (uri.IsAbsoluteUri == false) uri = uri.MakeAbsolute(umbracoContext.CleanedUmbracoUrl); - uri = UriUtility.UriToUmbraco(uri); + uri = uriUtility.UriToUmbraco(uri); var pcr = publishedRouter.CreateRequest(umbracoContext, uri); publishedRouter.TryRouteRequest(pcr); diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index ab95768f4b..2e9df383bf 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -22,6 +22,7 @@ using Umbraco.Core.Strings; using Umbraco.Core.Sync; using Umbraco.Web.Models.PublishedContent; using Umbraco.Web.PublishedCache; +using Umbraco.Web; using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidator; namespace Umbraco.Core.Runtime @@ -139,6 +140,7 @@ namespace Umbraco.Core.Runtime composition.SetCultureDictionaryFactory(); composition.Register(f => f.GetInstance().CreateDictionary(), Lifetime.Singleton); + composition.RegisterUnique(); // register the published snapshot accessor - the "current" published snapshot is in the umbraco context composition.RegisterUnique(); diff --git a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs index 44a6d32538..8db6b970bc 100644 --- a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs @@ -164,6 +164,7 @@ namespace Umbraco.Tests.Cache TestObjects.GetGlobalSettings(), Mock.Of(), IOHelper, + UriUtility, httpContextAccessor); // just assert it does not throw diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 2a7ce5924b..a7ef0ff721 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -82,7 +82,8 @@ namespace Umbraco.Tests.Cache.PublishedCache new WebSecurity(httpContextAccessor, Mock.Of(), globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); _cache = _umbracoContext.Content; } diff --git a/src/Umbraco.Tests/Misc/UriUtilityTests.cs b/src/Umbraco.Tests/Misc/UriUtilityTests.cs index 33a4b45249..0d0f6db61e 100644 --- a/src/Umbraco.Tests/Misc/UriUtilityTests.cs +++ b/src/Umbraco.Tests/Misc/UriUtilityTests.cs @@ -12,6 +12,8 @@ namespace Umbraco.Tests.Misc [TestFixture] public class UriUtilityTests { + + public UriUtility UriUtility { get; } = TestHelper.UriUtility; [TearDown] public void TearDown() { diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs index 7f6e09f3be..9281db2d29 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs @@ -76,7 +76,8 @@ namespace Umbraco.Tests.PublishedContent new WebSecurity(httpContextAccessor, Current.Services.UserService, globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); return umbracoContext; } diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs index 8d0a544c06..c9d11055ac 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs @@ -48,7 +48,8 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(urlAsString); var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); - var lookup = new ContentFinderByUrlAlias(Logger); + var lookup = + new ContentFinderByUrlAlias(Logger, Mock.Of(), VariationContextAccessor); var result = lookup.TryFindContent(frequest); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs index 60ed41593d..1a08153b4f 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs @@ -20,10 +20,16 @@ namespace Umbraco.Tests.Routing var properties = new[] { - new PublishedPropertyType("umbracoUrlAlias", Constants.DataTypes.Textbox, false, ContentVariation.Nothing, - new PropertyValueConverterCollection(Enumerable.Empty()), - Mock.Of(), - Mock.Of()), + new PublishedPropertyType( + propertyTypeAlias:"umbracoUrlAlias", + dataTypeId: Constants.DataTypes.Textbox, + isUserProperty:false, + variations: ContentVariation.Nothing, + propertyValueConverters:new PropertyValueConverterCollection(Enumerable.Empty()), + contentType:Mock.Of(), + publishedModelFactory:Mock.Of(), + factory:Mock.Of() + ) }; _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing); } @@ -57,7 +63,7 @@ namespace Umbraco.Tests.Routing if (expectedNode > 0) Assert.AreEqual(expectedCulture, request.Culture.Name); - var finder = new ContentFinderByUrlAlias(Logger); + var finder = new ContentFinderByUrlAlias(Logger, Mock.Of(), VariationContextAccessor); var result = finder.TryFindContent(request); if (expectedNode > 0) diff --git a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs index f74c68777e..ba07bbed82 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(urlAsString, template1.Id, globalSettings:globalSettings.Object); var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); - var lookup = new ContentFinderByUrlAndTemplate(Logger, ServiceContext.FileService); + var lookup = new ContentFinderByUrlAndTemplate(Logger, ServiceContext.FileService, TestObjects.GetUmbracoSettings(), ServiceContext.ContentTypeService); var result = lookup.TryFindContent(frequest); diff --git a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs index 3eb68aafb5..b9d669902d 100644 --- a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs +++ b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs @@ -60,6 +60,7 @@ namespace Umbraco.Tests.Routing GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, Logger, + UriUtility, PublishedUrlProvider).ToList(); Assert.AreEqual(1, urls.Count); @@ -80,7 +81,8 @@ namespace Umbraco.Tests.Routing var umbContext = GetUmbracoContext("http://localhost:8000"); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbContext); - var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), umbracoContextAccessor); + var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), + umbracoContextAccessor, UriUtility); var publishedUrlProvider = new UrlProvider( umbracoContextAccessor, TestHelper.WebRoutingSection, @@ -96,6 +98,7 @@ namespace Umbraco.Tests.Routing GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, Logger, + UriUtility, publishedUrlProvider).ToList(); Assert.AreEqual(1, urls.Count); @@ -124,14 +127,14 @@ namespace Umbraco.Tests.Routing var umbContext = GetUmbracoContext("http://localhost:8000"); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbContext); - var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), umbracoContextAccessor); + var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = new UrlProvider( umbracoContextAccessor, TestHelper.WebRoutingSection, new UrlProviderCollection(new []{urlProvider}), new MediaUrlProviderCollection(Enumerable.Empty()), Mock.Of() - ); + ); var publishedRouter = CreatePublishedRouter(Factory, contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(Logger) })); @@ -140,7 +143,9 @@ namespace Umbraco.Tests.Routing GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, Logger, - publishedUrlProvider).ToList(); + UriUtility, + publishedUrlProvider + ).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("/home/sub1/", urls[0].Text); diff --git a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs index b217f81aea..2798e50a26 100644 --- a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Routing new FileUploadPropertyEditor(logger, mediaFileSystemMock, contentSection, dataTypeService, LocalizationService, LocalizedTextService, ShortStringHelper, umbracoSettingsSection), new ImageCropperPropertyEditor(logger, mediaFileSystemMock, contentSection, dataTypeService, LocalizationService, IOHelper, ShortStringHelper, LocalizedTextService, umbracoSettingsSection), })); - _mediaUrlProvider = new DefaultMediaUrlProvider(new Lazy(() => propertyEditors)); + _mediaUrlProvider = new DefaultMediaUrlProvider(new Lazy(() => propertyEditors), UriUtility); } public override void TearDown() diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index c601c48148..de7e6d52b6 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -43,6 +43,7 @@ namespace Umbraco.Tests.Routing null, // FIXME: PublishedRouter complexities... Mock.Of(), new RoutableDocumentFilter(globalSettings, IOHelper), + UriUtility, AppCaches.RequestCache ); diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs index 4b02a67c8c..481d03bce5 100644 --- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs @@ -50,11 +50,10 @@ namespace Umbraco.Tests.Routing var umbracoSettings = Current.Configs.Settings(); - var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); var requestHandlerMock = Mock.Get(umbracoSettings.RequestHandler); @@ -130,7 +129,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); var result = publishedUrlProvider.GetUrl(nodeId); @@ -159,7 +158,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); var result = publishedUrlProvider.GetUrl(nodeId); @@ -202,7 +201,7 @@ namespace Umbraco.Tests.Routing snapshotService: snapshotService.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); //even though we are asking for a specific culture URL, there are no domains assigned so all that can be returned is a normal relative url. @@ -258,7 +257,7 @@ namespace Umbraco.Tests.Routing snapshotService: snapshotService.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); @@ -313,7 +312,7 @@ namespace Umbraco.Tests.Routing snapshotService: snapshotService.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); @@ -335,7 +334,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, globalSettings: globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); Assert.AreEqual("/home/sub1/custom-sub-1/", publishedUrlProvider.GetUrl(1177)); @@ -353,7 +352,7 @@ namespace Umbraco.Tests.Routing var umbracoSettings = Current.Configs.Settings(); var urlProvider = new DefaultUrlProvider(umbracoSettings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), UmbracoContextAccessor); + new SiteDomainHelper(), UmbracoContextAccessor, UriUtility); var umbracoContext = GetUmbracoContext("http://example.com/test", 1111, globalSettings: globalSettings.Object); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); diff --git a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs index 59fb5629a8..ab2883ac37 100644 --- a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs @@ -186,7 +186,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains1(); @@ -220,7 +220,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains2(); @@ -246,7 +246,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains3(); @@ -278,7 +278,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains4(); @@ -300,7 +300,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains4(); @@ -364,7 +364,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://domain1.com/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains4(); @@ -389,7 +389,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("http://domain1.com/en/test", 1111, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); SetDomains5(); diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 5b4ab20b49..ad6e7b5408 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -46,7 +46,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(url, 9999, globalSettings:globalSettings.Object); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var urlProvider = new DefaultUrlProvider(settings.RequestHandler, Logger, globalSettings.Object, - new SiteDomainHelper(), umbracoContextAccessor); + new SiteDomainHelper(), umbracoContextAccessor, UriUtility); var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider); Assert.AreEqual("http://domain2.com/1001-1-1/", publishedUrlProvider.GetUrl(100111, UrlMode.Absolute)); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 2e4497b3b9..d0b63f8492 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -125,7 +125,8 @@ namespace Umbraco.Tests.Scoping new WebSecurity(httpContextAccessor, Current.Services.UserService, globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); if (setSingleton) Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext; diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs index cb50ae2c17..30c61350b9 100644 --- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs +++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs @@ -36,7 +36,8 @@ namespace Umbraco.Tests.Security Mock.Of(), new WebSecurity(httpContextAccessor, Current.Services.UserService, globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Install); var mgr = new BackOfficeCookieManager( @@ -58,7 +59,8 @@ namespace Umbraco.Tests.Security new WebSecurity(httpContextAccessor, Current.Services.UserService, globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Run); var mgr = new BackOfficeCookieManager(Mock.Of(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache); diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs index 3ee93e2662..2eb8decd1c 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs @@ -143,7 +143,8 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting webSecurity.Object, globalSettings, new TestVariationContextAccessor(), - TestHelper.IOHelper); + TestHelper.IOHelper, + TestHelper.UriUtility); //replace it umbracoContextAccessor.UmbracoContext = umbCtx; diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 5dc8ba2a11..41b97ac580 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -102,6 +102,8 @@ namespace Umbraco.Tests.TestHelpers public static IIOHelper IOHelper { get; } = new IOHelper(GetHostingEnvironment()); public static IMainDom MainDom { get; } = new MainDom(Mock.Of(), GetHostingEnvironment(), new MainDomSemaphoreLock(Mock.Of(), GetHostingEnvironment())); + public static UriUtility UriUtility { get; } = new UriUtility(GetHostingEnvironment()); + public static IWebRoutingSection WebRoutingSection => SettingsForTests.GetDefaultUmbracoSettings().WebRouting; /// diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index d7f03a3aee..25588bed62 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -133,6 +133,7 @@ namespace Umbraco.Tests.TestHelpers globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); return umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 1762f7716a..c2a44026d6 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -381,7 +381,8 @@ namespace Umbraco.Tests.TestHelpers Factory.GetInstance(), IOHelper), globalSettings ?? Factory.GetInstance(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); if (setSingleton) Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext; diff --git a/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs index d34a784df6..26bed55cbc 100644 --- a/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs +++ b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs @@ -44,6 +44,7 @@ namespace Umbraco.Tests.Testing.Objects globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); return umbracoContextFactory; diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 687e1f4ad7..f10c18492a 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -115,6 +115,7 @@ namespace Umbraco.Tests.Testing protected IJsonSerializer JsonNetSerializer { get; } = new JsonNetSerializer(); protected IIOHelper IOHelper { get; private set; } + protected UriUtility UriUtility => new UriUtility(HostingEnvironment); protected IPublishedUrlProvider PublishedUrlProvider => Factory.GetInstance(); protected IDataTypeService DataTypeService => Factory.GetInstance(); protected IPasswordHasher PasswordHasher => Factory.GetInstance(); @@ -130,7 +131,7 @@ namespace Umbraco.Tests.Testing protected virtual IProfilingLogger ProfilingLogger => Factory.GetInstance(); - protected IHostingEnvironment HostingEnvironment => Factory.GetInstance(); + protected IHostingEnvironment HostingEnvironment { get; } = new AspNetHostingEnvironment(SettingsForTests.GetDefaultHostingSettings()); protected IIpResolver IpResolver => Factory.GetInstance(); protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance(); protected AppCaches AppCaches => Factory.GetInstance(); @@ -163,20 +164,18 @@ namespace Umbraco.Tests.Testing var proflogger = new ProfilingLogger(logger, profiler); IOHelper = TestHelper.IOHelper; - TypeFinder = new TypeFinder(logger); var appCaches = GetAppCaches(); var globalSettings = SettingsForTests.GetDefaultGlobalSettings(); - var hostingSettings = SettingsForTests.GetDefaultHostingSettings(); var settings = SettingsForTests.GetDefaultUmbracoSettings(); - IHostingEnvironment hostingEnvironment = new AspNetHostingEnvironment(hostingSettings); + IBackOfficeInfo backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, IOHelper, settings, logger); IIpResolver ipResolver = new AspNetIpResolver(); UmbracoVersion = new UmbracoVersion(globalSettings); LocalizedTextService = new LocalizedTextService(new Dictionary>(), logger); - var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, hostingEnvironment, proflogger, Options.TypeLoader); + var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, HostingEnvironment, proflogger, Options.TypeLoader); var register = TestHelper.GetRegister(); @@ -187,6 +186,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(IOHelper); + Composition.RegisterUnique(UriUtility); Composition.RegisterUnique(UmbracoVersion); Composition.RegisterUnique(TypeFinder); Composition.RegisterUnique(LocalizedTextService); @@ -195,7 +195,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(profiler); Composition.RegisterUnique(proflogger); Composition.RegisterUnique(appCaches); - Composition.RegisterUnique(hostingEnvironment); + Composition.RegisterUnique(HostingEnvironment); Composition.RegisterUnique(backOfficeInfo); Composition.RegisterUnique(ipResolver); Composition.RegisterUnique(); @@ -522,7 +522,7 @@ namespace Umbraco.Tests.Testing Current.Reset(); // disposes the factory // reset all other static things that should not be static ;( - UriUtility.ResetAppDomainAppVirtualPath(); + UriUtility.ResetAppDomainAppVirtualPath(HostingEnvironment); SettingsForTests.Reset(); // FIXME: should it be optional? // clear static events diff --git a/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs b/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs index 3733899e88..98301076ef 100644 --- a/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/RenderIndexActionSelectorAttributeTests.cs @@ -73,6 +73,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -103,6 +104,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -133,6 +135,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -163,6 +166,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), TestHelper.IOHelper, + TestHelper.UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs index b6d2d92da0..52f90636aa 100644 --- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs @@ -49,6 +49,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), IOHelper, + UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -77,6 +78,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), IOHelper, + UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -108,6 +110,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), IOHelper, + UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); @@ -146,6 +149,7 @@ namespace Umbraco.Tests.Web.Mvc globalSettings, Mock.Of(), IOHelper, + UriUtility, httpContextAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 16da66360e..a03c84f0b0 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -444,7 +444,8 @@ namespace Umbraco.Tests.Web.Mvc new WebSecurity(httpContextAccessor, Current.Services.UserService, globalSettings, IOHelper), globalSettings, new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); //if (setSingleton) //{ diff --git a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs index 6623cf3df3..76edcd4152 100644 --- a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs +++ b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs @@ -35,7 +35,8 @@ namespace Umbraco.Tests.Web new WebSecurity(httpContextAccessor, Current.Services.UserService, TestObjects.GetGlobalSettings(), IOHelper), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var r1 = new RouteData(); r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); @@ -54,7 +55,8 @@ namespace Umbraco.Tests.Web new WebSecurity(httpContextAccessor, Current.Services.UserService, TestObjects.GetGlobalSettings(), IOHelper), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var r1 = new RouteData(); r1.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbCtx); @@ -83,7 +85,8 @@ namespace Umbraco.Tests.Web new WebSecurity(httpContextAccessor, Current.Services.UserService, TestObjects.GetGlobalSettings(), IOHelper), TestObjects.GetGlobalSettings(), new TestVariationContextAccessor(), - IOHelper); + IOHelper, + UriUtility); var httpContext = Mock.Of(); diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index ac0092ceb6..29c03f7cfa 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -8,7 +8,6 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; -using Umbraco.Web.Composing; using Umbraco.Web.Editors; using Umbraco.Web.Routing; @@ -17,7 +16,7 @@ namespace Umbraco.Web.Macros /// /// Legacy class used by macros which converts a published content item into a hashset of values /// - public class PublishedContentHashtableConverter + internal class PublishedContentHashtableConverter { #region Constructors diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs index 58fc0c5c1e..d418bf153d 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs @@ -32,6 +32,7 @@ namespace Umbraco.Web.Models.Mapping private readonly IUserService _userService; private readonly IVariationContextAccessor _variationContextAccessor; private readonly IPublishedUrlProvider _publishedUrlProvider; + private readonly UriUtility _uriUtility; private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; private readonly ContentSavedStateMapper _stateMapper; private readonly ContentBasicSavedStateMapper _basicStateMapper; @@ -39,7 +40,7 @@ namespace Umbraco.Web.Models.Mapping public ContentMapDefinition(CommonMapper commonMapper, ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService, IContentService contentService, IContentTypeService contentTypeService, IFileService fileService, IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, ILocalizationService localizationService, ILogger logger, - IUserService userService, IVariationContextAccessor variationContextAccessor, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IPublishedUrlProvider publishedUrlProvider) + IUserService userService, IVariationContextAccessor variationContextAccessor, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, UriUtility uriUtility, IPublishedUrlProvider publishedUrlProvider) { _commonMapper = commonMapper; _cultureDictionary = cultureDictionary; @@ -53,6 +54,7 @@ namespace Umbraco.Web.Models.Mapping _logger = logger; _userService = userService; _variationContextAccessor = variationContextAccessor; + _uriUtility = uriUtility; _publishedUrlProvider = publishedUrlProvider; _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider); @@ -179,7 +181,7 @@ namespace Umbraco.Web.Models.Mapping var urls = umbracoContext == null ? new[] { UrlInfo.Message("Cannot generate urls without a current Umbraco Context") } - : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _logger, _publishedUrlProvider).ToArray(); + : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _logger, _uriUtility, _publishedUrlProvider).ToArray(); return urls; } diff --git a/src/Umbraco.Web/Net/AspNetIpResolver.cs b/src/Umbraco.Web/Net/AspNetIpResolver.cs index 8cec45ff30..7eaca54663 100644 --- a/src/Umbraco.Web/Net/AspNetIpResolver.cs +++ b/src/Umbraco.Web/Net/AspNetIpResolver.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web { public string GetCurrentRequestIpAddress() { - var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); + var httpContext = HttpContext.Current is null ? null : new HttpContextWrapper(HttpContext.Current); var ip = httpContext.GetCurrentRequestIpAddress(); if (ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; return ip; diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 8bc3b9d4e9..da3342a682 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Umbraco.Core; +using Umbraco.Web.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -74,7 +75,7 @@ namespace Umbraco.Web.PropertyEditors /// /// A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for display in the editor /// - public class RichTextPropertyValueEditor : DataValueEditor, IDataValueReference + internal class RichTextPropertyValueEditor : DataValueEditor, IDataValueReference { private IUmbracoContextAccessor _umbracoContextAccessor; private readonly HtmlImageSourceParser _imageSourceParser; diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index e5b1285346..0c8f663e38 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Web; using Examine; using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -50,8 +51,8 @@ namespace Umbraco.Web Current.Configs.Settings().WebRouting.DisableAlternativeTemplates, Current.Configs.Settings().WebRouting.ValidateAlternativeTemplates, templateId); - } + public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) { return content.IsAllowedTemplate( @@ -700,26 +701,27 @@ namespace Umbraco.Web #region Url /// - /// Gets the url of the content item. - /// - /// - /// If the content item is a document, then this method returns the url of the - /// document. If it is a media, then this methods return the media url for the - /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other - /// properties. - /// 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 - /// specified culture. Otherwise, it is the invariant url. - /// - public static string Url(this IPublishedContent content, string culture = null, UrlMode mode = UrlMode.Default) - { - var umbracoContext = Current.UmbracoContext; + /// Gets the url of the content item. + /// + /// + /// If the content item is a document, then this method returns the url of the + /// document. If it is a media, then this methods return the media url for the + /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other + /// properties. + /// 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 + /// specified culture. Otherwise, it is the invariant url. + /// + public static string Url(this IPublishedContent content, string culture = null, UrlMode mode = UrlMode.Default) + { + var umbracoContext = Current.UmbracoContext; - if (umbracoContext == null) - throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext is null."); + if (umbracoContext == null) + throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext is null."); + + return content.Url(Current.PublishedUrlProvider, culture, mode); + } - return content.Url(Current.PublishedUrlProvider, culture, mode); - } #endregion } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 7f40c33dda..0b0e6b6fee 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -211,11 +211,6 @@ - - - - - @@ -335,13 +330,6 @@ - - - - - - - @@ -388,7 +376,6 @@ - @@ -478,7 +465,6 @@ - @@ -624,16 +610,9 @@ - - - - - - - @@ -655,24 +634,19 @@ - - - - Code - True True diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 2daa85f057..2dacc60e73 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -19,6 +19,7 @@ namespace Umbraco.Web private readonly IHttpContextAccessor _httpContextAccessor; private readonly IGlobalSettings _globalSettings; private readonly IIOHelper _ioHelper; + private readonly UriUtility _uriUtility; private readonly Lazy _publishedSnapshot; private string _previewToken; private bool? _previewing; @@ -32,7 +33,8 @@ namespace Umbraco.Web IWebSecurity webSecurity, IGlobalSettings globalSettings, IVariationContextAccessor variationContextAccessor, - IIOHelper ioHelper) + IIOHelper ioHelper, + UriUtility uriUtility) { if (httpContextAccessor == null) throw new ArgumentNullException(nameof(httpContextAccessor)); if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService)); @@ -41,6 +43,7 @@ namespace Umbraco.Web _httpContextAccessor = httpContextAccessor; _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); + _uriUtility = uriUtility; // ensure that this instance is disposed when the request terminates, though we *also* ensure // this happens in the Umbraco module since the UmbracoCOntext is added to the HttpContext items. @@ -67,7 +70,7 @@ namespace Umbraco.Web // see: http://issues.umbraco.org/issue/U4-1890 // OriginalRequestUrl = GetRequestFromContext()?.Url ?? new Uri("http://localhost"); - CleanedUmbracoUrl = UriUtility.UriToUmbraco(OriginalRequestUrl); + CleanedUmbracoUrl = _uriUtility.UriToUmbraco(OriginalRequestUrl); } /// diff --git a/src/Umbraco.Web/UmbracoContextFactory.cs b/src/Umbraco.Web/UmbracoContextFactory.cs index 8a109e4c55..d627d9e823 100644 --- a/src/Umbraco.Web/UmbracoContextFactory.cs +++ b/src/Umbraco.Web/UmbracoContextFactory.cs @@ -1,17 +1,11 @@ using System; -using System.Collections.Generic; using System.IO; using System.Text; -using System.Threading; -using System.Web; -using System.Web.Hosting; using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web.PublishedCache; -using Umbraco.Web.Routing; using Umbraco.Web.Security; namespace Umbraco.Web @@ -32,11 +26,21 @@ namespace Umbraco.Web private readonly IUserService _userService; private readonly IIOHelper _ioHelper; private readonly IHttpContextAccessor _httpContextAccessor; + private readonly UriUtility _uriUtility; /// /// Initializes a new instance of the class. /// - public UmbracoContextFactory(IUmbracoContextAccessor umbracoContextAccessor, IPublishedSnapshotService publishedSnapshotService, IVariationContextAccessor variationContextAccessor, IDefaultCultureAccessor defaultCultureAccessor, IGlobalSettings globalSettings, IUserService userService, IIOHelper ioHelper, IHttpContextAccessor httpContextAccessor) + public UmbracoContextFactory( + IUmbracoContextAccessor umbracoContextAccessor, + IPublishedSnapshotService publishedSnapshotService, + IVariationContextAccessor variationContextAccessor, + IDefaultCultureAccessor defaultCultureAccessor, + IGlobalSettings globalSettings, + IUserService userService, + IIOHelper ioHelper, + UriUtility uriUtility, + IHttpContextAccessor httpContextAccessor) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); _publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService)); @@ -45,6 +49,7 @@ namespace Umbraco.Web _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _ioHelper = ioHelper; + _uriUtility = uriUtility; _httpContextAccessor = httpContextAccessor; } @@ -64,7 +69,7 @@ namespace Umbraco.Web var webSecurity = new WebSecurity(_httpContextAccessor, _userService, _globalSettings, _ioHelper); - return new UmbracoContext(_httpContextAccessor, _publishedSnapshotService, webSecurity, _globalSettings, _variationContextAccessor, _ioHelper); + return new UmbracoContext(_httpContextAccessor, _publishedSnapshotService, webSecurity, _globalSettings, _variationContextAccessor, _ioHelper, _uriUtility); } /// diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 3c40b42026..a311d76f73 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -40,6 +40,7 @@ namespace Umbraco.Web private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly RoutableDocumentFilter _routableDocumentLookup; private readonly IRequestCache _requestCache; + private readonly UriUtility _uriUtility; public UmbracoInjectedModule( IGlobalSettings globalSettings, @@ -48,6 +49,7 @@ namespace Umbraco.Web IPublishedRouter publishedRouter, IUmbracoContextFactory umbracoContextFactory, RoutableDocumentFilter routableDocumentLookup, + UriUtility uriUtility, IRequestCache requestCache) { _globalSettings = globalSettings; @@ -56,6 +58,7 @@ namespace Umbraco.Web _publishedRouter = publishedRouter; _umbracoContextFactory = umbracoContextFactory; _routableDocumentLookup = routableDocumentLookup; + _uriUtility = uriUtility; _requestCache = requestCache; } @@ -121,7 +124,7 @@ namespace Umbraco.Web var isRoutableAttempt = EnsureUmbracoRoutablePage(umbracoContext, httpContext); // raise event here - UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext, httpContext)); + UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext)); if (isRoutableAttempt.Success == false) return; httpContext.Trace.Write("UmbracoModule", "Umbraco request confirmed"); @@ -210,7 +213,7 @@ namespace Umbraco.Web case RuntimeLevel.Upgrade: // redirect to install ReportRuntime(level, "Umbraco must install or upgrade."); - var installPath = UriUtility.ToAbsolute(Constants.SystemDirectories.Install); + var installPath = _uriUtility.ToAbsolute(Constants.SystemDirectories.Install); var installUrl = $"{installPath}/?redir=true&url={HttpUtility.UrlEncode(uri.ToString())}"; httpContext.Response.Redirect(installUrl, true); return false; // cannot serve content @@ -242,7 +245,7 @@ namespace Umbraco.Web _logger.Warn("Umbraco has no content"); const string noContentUrl = "~/config/splashes/noNodes.aspx"; - httpContext.RewritePath(UriUtility.ToAbsolute(noContentUrl)); + httpContext.RewritePath(_uriUtility.ToAbsolute(noContentUrl)); return false; } @@ -430,7 +433,7 @@ namespace Umbraco.Web _logger.Verbose("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(Current.UmbracoContext.ObjectCreated).TotalMilliseconds); } - UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext, new HttpContextWrapper(httpContext))); + UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext)); DisposeRequestCacheItems(httpContext, _requestCache); };