fix NiceUrl and add more tests

This commit is contained in:
Stephan
2012-09-30 12:24:23 -02:00
parent 926427ff68
commit 3e99dd0d55
8 changed files with 329 additions and 164 deletions

View File

@@ -312,16 +312,21 @@ namespace Umbraco.Core.Configuration
get { return "packages.umbraco.org"; }
}
static bool? _useDomainPrefixes = null;
/// <summary>
/// Gets a value indicating whether umbraco will use domain prefixes.
/// </summary>
/// <value><c>true</c> if umbraco will use domain prefixes; otherwise, <c>false</c>.</value>
// TODO rename as EnforceAbsoluteUrls
public static bool UseDomainPrefixes
{
get
{
try
{
if (_useDomainPrefixes.HasValue)
return _useDomainPrefixes.Value;
bool result;
if (bool.TryParse(GetKey("/settings/requestHandler/useDomainPrefixes"), out result))
return result;
@@ -332,6 +337,11 @@ namespace Umbraco.Core.Configuration
return false;
}
}
// for unit tests only
internal set
{
_useDomainPrefixes = value;
}
}
static bool? _addTrailingSlash = null;
@@ -365,6 +375,7 @@ namespace Umbraco.Core.Configuration
return false;
}
}
// for unit tests only
internal set
{
_addTrailingSlash = value;

View File

@@ -78,23 +78,6 @@ namespace Umbraco.Tests.Routing
}
}
//[TestCase(1046, "/home.aspx")]
//[TestCase(1173, "/home/sub1.aspx")]
//[TestCase(1174, "/home/sub1/sub2.aspx")]
//[TestCase(1176, "/home/sub1/sub-3.aspx")]
//[TestCase(1177, "/home/sub1/custom-sub-1.aspx")]
//[TestCase(1178, "/home/sub1/custom-sub-2.aspx")]
//[TestCase(1175, "/home/sub-2.aspx")]
//[TestCase(1172, "/test-page.aspx")]
//public void Get_Nice_Url_Not_Hiding_Top_Level_No_Directory_Urls(int nodeId, string niceUrlMatch)
//{
// var routingContext = GetRoutingContext("/test", 1111);
// var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
// Assert.AreEqual(niceUrlMatch, result);
//}
// test hideTopLevelNodeFromPath false
[TestCase(1046, "/home")]
[TestCase(1173, "/home/sub1")]
@@ -111,6 +94,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
Assert.AreEqual(niceUrlMatch, result);
@@ -118,25 +102,6 @@ namespace Umbraco.Tests.Routing
// no need for umbracoUseDirectoryUrls test = should be handled by UriUtilityTests
//[TestCase(1046, "/")]
//[TestCase(1173, "/sub1.aspx")]
//[TestCase(1174, "/sub1/sub2.aspx")]
//[TestCase(1176, "/sub1/sub-3.aspx")]
//[TestCase(1177, "/sub1/custom-sub-1.aspx")]
//[TestCase(1178, "/sub1/custom-sub-2.aspx")]
//[TestCase(1175, "/sub-2.aspx")]
//[TestCase(1172, "/test-page.aspx")]
//public void Get_Nice_Url_Hiding_Top_Level_No_Directory_Urls(int nodeId, string niceUrlMatch)
//{
// var routingContext = GetRoutingContext("/test", 1111);
// ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
// var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
// Assert.AreEqual(niceUrlMatch, result);
//}
// test hideTopLevelNodeFromPath true
[TestCase(1046, "/")]
[TestCase(1173, "/sub1")]
@@ -153,9 +118,46 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
Assert.AreEqual(niceUrlMatch, result);
}
[Test]
public void Get_Nice_Url_Relative_Or_Absolute()
{
var routingContext = GetRoutingContext("http://example.com/test", 1111);
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
Assert.AreEqual("/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
}
[Test]
public void Get_Nice_Url_Unpublished()
{
var routingContext = GetRoutingContext("http://example.com/test", 1111);
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
}
}
}

View File

@@ -91,6 +91,22 @@ namespace Umbraco.Tests.Routing
Domain.MakeNew("http://domain3.com/fr", 10032, langFr.id);
}
void SetDomains5()
{
var langEn = Language.GetByCultureCode("en-US");
var langFr = Language.GetByCultureCode("fr-FR");
Domain.MakeNew("http://domain1.com/en", 10011, langEn.id);
Domain.MakeNew("http://domain1a.com/en", 10011, langEn.id);
Domain.MakeNew("http://domain1b.com/en", 10011, langEn.id);
Domain.MakeNew("http://domain1.com/fr", 10012, langFr.id);
Domain.MakeNew("http://domain1a.com/fr", 10012, langFr.id);
Domain.MakeNew("http://domain1b.com/fr", 10012, langFr.id);
Domain.MakeNew("http://domain3.com/en", 10031, langEn.id);
Domain.MakeNew("http://domain3.com/fr", 10032, langFr.id);
}
protected override string GetXmlContent(int templateId)
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
@@ -194,6 +210,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
InitializeLanguagesAndDomains();
SetDomains1();
@@ -223,6 +240,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
InitializeLanguagesAndDomains();
SetDomains2();
@@ -244,6 +262,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
InitializeLanguagesAndDomains();
SetDomains3();
@@ -268,6 +287,7 @@ namespace Umbraco.Tests.Routing
public void Get_Nice_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected)
{
var routingContext = GetRoutingContext("/test", 1111);
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
@@ -287,6 +307,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
InitializeLanguagesAndDomains();
SetDomains4();
@@ -337,5 +358,52 @@ namespace Umbraco.Tests.Routing
Assert.IsTrue(ids.ContainsKey(route));
Assert.AreEqual(id, ids[route]);
}
[Test]
public void Get_Nice_Url_Relative_Or_Absolute()
{
var routingContext = GetRoutingContext("http://domain1.com/test", 1111);
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
InitializeLanguagesAndDomains();
SetDomains4();
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
Assert.AreEqual("/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
Assert.AreEqual("http://domain1.com/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
Assert.AreEqual("http://domain1.com/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
}
[Test]
public void Get_Nice_Url_Alternate()
{
var routingContext = GetRoutingContext("http://domain1.com/test", 1111);
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
InitializeLanguagesAndDomains();
SetDomains5();
var result = routingContext.NiceUrlProvider.GetAllAbsoluteNiceUrls(100111);
// will always get absolute urls
// all of them
// including the local one - duplicate?! - then must manually exclude?
Assert.AreEqual(3, result.Count());
Assert.IsTrue(result.Contains("http://domain1.com/en/1001-1-1"));
Assert.IsTrue(result.Contains("http://domain1a.com/en/1001-1-1"));
Assert.IsTrue(result.Contains("http://domain1b.com/en/1001-1-1"));
}
}
}

View File

@@ -86,5 +86,37 @@ namespace Umbraco.Tests
{
return new Uri(url, url.StartsWith("http:") ? UriKind.Absolute : UriKind.Relative);
}
//
[TestCase("/", "/", "/")]
[TestCase("/", "/foo", "/foo")]
[TestCase("/", "~/foo", "/foo")]
[TestCase("/vdir", "/", "/vdir/")]
[TestCase("/vdir", "/foo", "/vdir/foo")]
[TestCase("/vdir", "/foo/", "/vdir/foo/")]
[TestCase("/vdir", "~/foo", "/vdir/foo")]
public void Uri_To_Absolute(string virtualPath, string sourceUrl, string expectedUrl)
{
UriUtility.SetAppDomainAppVirtualPath(virtualPath);
var resultUrl = UriUtility.ToAbsolute(sourceUrl);
Assert.AreEqual(expectedUrl, resultUrl);
}
//
[TestCase("/", "/", "/")]
[TestCase("/", "/foo", "/foo")]
[TestCase("/", "/foo/", "/foo/")]
[TestCase("/vdir", "/vdir", "/")]
[TestCase("/vdir", "/vdir/", "/")]
[TestCase("/vdir", "/vdir/foo", "/foo")]
[TestCase("/vdir", "/vdir/foo/", "/foo/")]
public void Url_To_App_Relative(string virtualPath, string sourceUrl, string expectedUrl)
{
UriUtility.SetAppDomainAppVirtualPath(virtualPath);
var resultUrl = UriUtility.ToAppRelative(sourceUrl);
Assert.AreEqual(expectedUrl, resultUrl);
}
}
}

View File

@@ -18,7 +18,6 @@ namespace Umbraco.Web.Routing
/// </summary>
internal class NiceUrlProvider
{
internal const string NullUrl = "#";
/// <summary>
@@ -30,37 +29,56 @@ namespace Umbraco.Web.Routing
{
_umbracoContext = umbracoContext;
_publishedContentStore = publishedContentStore;
this.EnforceAbsoluteUrls = false;
}
private readonly UmbracoContext _umbracoContext;
private readonly IPublishedContentStore _publishedContentStore;
public bool EnforceAbsoluteUrls { get; set; }
#region GetNiceUrl
/// <summary>
/// Gets the nice url of a node.
/// </summary>
/// <param name="nodeId">The node id.</param>
/// <param name="nodeId">The node identifier.</param>
/// <returns>The nice url for the node.</returns>
/// <remarks>The url is absolute or relative depending on the current url.</remarks>
/// <remarks>The url is absolute or relative depending on the current url, settings, and options.</remarks>
public string GetNiceUrl(int nodeId)
{
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, false);
var absolute = UmbracoSettings.UseDomainPrefixes || this.EnforceAbsoluteUrls;
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
}
/// <summary>
/// Gets the nice url of a node.
/// </summary>
/// <param name="nodeId">The node identifier.</param>
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
/// <returns>The nice url for the node.</returns>
/// <remarks>The url is absolute or relative depending on the current url, unless <c>absolute</c> is true, in which case the url is always absolute.</remarks>
public string GetNiceUrl(int nodeId, bool absolute)
{
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
}
/// <summary>
/// Gets the nice url of a node.
/// </summary>
/// <param name="nodeId">The node id.</param>
/// <param name="current">The current url.</param>
/// <param name="current">The current absolute url.</param>
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
/// <returns>The nice url for the node.</returns>
/// <remarks>The url is absolute or relative depending on the current url, unless absolute is true, and then it is always absolute.</remarks>
/// <remarks>The url is absolute or relative depending on url indicated by <c>current</c>, unless <c>absolute</c> is true, in which case the url is always absolute.</remarks>
public string GetNiceUrl(int nodeId, Uri current, bool absolute)
{
Uri domainUri;
string path;
if (!current.IsAbsoluteUri)
throw new ArgumentException("Current url must be absolute.", "current");
// do not read cache if previewing
var route = _umbracoContext.InPreviewMode
? null
@@ -105,26 +123,7 @@ namespace Umbraco.Web.Routing
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
if (domainUri == null && global::umbraco.GlobalSettings.HideTopLevelNodeFromPath)
{
// in theory if hideTopLevelNodeFromPath is true, then there should be only once
// top-level node, or else domains should be assigned. but for backward compatibility
// we add this check - we look for the document matching "/" and if it's not us, then
// we do not hide the top level path
// it has to be taken care of in IPublishedContentStore.GetDocumentByRoute too so if
// "/foo" fails (looking for "/*/foo") we try also "/foo".
// this does not make much sense anyway esp. if both "/foo/" and "/bar/foo" exist, but
// that's the way it works pre-4.10 and we try to be backward compat for the time being
if (node.Parent == null)
{
var rootNode = _publishedContentStore.GetDocumentByRoute(_umbracoContext, "/", true);
if (rootNode.Id == node.Id) // remove only if we're the default node
pathParts.RemoveAt(pathParts.Count - 1);
}
else
{
pathParts.RemoveAt(pathParts.Count - 1);
}
}
ApplyHideTopLevelNodeFromPath(node, pathParts);
// assemble the route
pathParts.Reverse();
@@ -140,6 +139,15 @@ namespace Umbraco.Web.Routing
return AssembleUrl(domainUri, path, current, absolute).ToString();
}
#endregion
#region GetAlternateNiceUrls
public IEnumerable<string> GetAllAbsoluteNiceUrls(int nodeId)
{
return GetAlternateNiceUrls(nodeId, _umbracoContext.UmbracoUrl);
}
/// <summary>
/// Gets the nice urls of a node.
/// </summary>
@@ -147,7 +155,7 @@ namespace Umbraco.Web.Routing
/// <param name="current">The current url.</param>
/// <returns>An enumeration of all valid urls for the node.</returns>
/// <remarks>The urls are absolute. A node can have more than one url if more than one domain is defined.</remarks>
public IEnumerable<string> GetNiceUrls(int nodeId, Uri current)
public IEnumerable<string> GetAlternateNiceUrls(int nodeId, Uri current)
{
// this is for editContent.aspx which had its own, highly buggy, implementation of NiceUrl...
//TODO: finalize & test implementation then replace in editContent.aspx
@@ -160,55 +168,77 @@ namespace Umbraco.Web.Routing
? null
: _umbracoContext.RoutesCache.GetRoute(nodeId);
if (route != null)
if (!string.IsNullOrEmpty(route))
{
// route is <id>/<path> eg "-1/", "-1/foo", "123/", "123/foo/bar"...
// there was a route in the cache - extract domainUri and path
// route is /<path> or <domainRootId>/<path>
int pos = route.IndexOf('/');
path = route.Substring(pos);
int id = int.Parse(route.Substring(0, pos)); // will be -1 or 1234
domainUris = id > 0 ? DomainUrisAtNode(id, current) : new Uri[] { };
path = pos == 0 ? route : route.Substring(pos);
domainUris = pos == 0 ? new Uri[] { } : DomainUrisAtNode(int.Parse(route.Substring(0, pos)), current);
}
else
{
// there was no route in the cache - create a route
var node = _publishedContentStore.GetDocumentById(_umbracoContext, nodeId);
if (node == null)
return new string[] { NullUrl }; // legacy wrote to the log here...
var pathParts = new List<string>();
int id = nodeId;
domainUris = DomainUrisAtNode(id, current);
while (!domainUris.Any() && id > 0)
{
LogHelper.Warn<NiceUrlProvider>(
"Couldn't find any page with nodeId={0}. This is most likely caused by the page not being published.",
nodeId);
return new string[] { NullUrl };
}
// walk up from that node until we hit a node with domains,
// or we reach the content root, collecting urls in the way
var pathParts = new List<string>();
var n = node;
domainUris = DomainUrisAtNode(n.Id, current);
while (!domainUris.Any() && n != null) // n is null at root
{
// get the url
var urlName = node.UrlName;
pathParts.Add(urlName);
node = node.Parent; //set to parent node
id = node.Id;
domainUris = id > 0 ? DomainUrisAtNode(id, current) : new Uri[] { };
// move to parent node
n = n.Parent;
domainUris = n == null ? new Uri[] { } : DomainUrisAtNode(n.Id, current);
}
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
if (!domainUris.Any() && global::umbraco.GlobalSettings.HideTopLevelNodeFromPath)
pathParts.RemoveAt(pathParts.Count - 1);
ApplyHideTopLevelNodeFromPath(node, pathParts);
// assemble the route
pathParts.Reverse();
path = "/" + string.Join("/", pathParts); // will be "/" or "/foo" or "/foo/bar" etc
route = id.ToString() + path;
route = (n == null ? "" : n.Id.ToString()) + path;
// do not store if previewing
if (!_umbracoContext.InPreviewMode)
_umbracoContext.RoutesCache.Store(nodeId, route);
}
// assemble the alternate urls from domainUris (maybe empty) and path
return AssembleUrls(domainUris, path, current).Select(uri => uri.ToString());
}
#endregion
#region Utilities
Uri AssembleUrl(Uri domainUri, string path, Uri current, bool absolute)
{
Uri uri;
if (domainUri == null)
{
// no domain was found : return a relative url, add vdir if any
uri = new Uri(SystemDirectories.Root + path, UriKind.Relative);
// no domain was found : return an absolute or relative url
// handle vdir if any
if (!absolute || current == null)
uri = new Uri(UriUtility.ToAbsolute(path), UriKind.Relative);
else
uri = new Uri(current.GetLeftPart(UriPartial.Authority) + UriUtility.ToAbsolute(path));
}
else
{
@@ -229,17 +259,26 @@ namespace Umbraco.Web.Routing
return path == "/" ? path : path.TrimEnd('/');
}
// always build absolute urls unless we really cannot
IEnumerable<Uri> AssembleUrls(IEnumerable<Uri> domainUris, string path, Uri current)
{
if (domainUris.Any())
List<Uri> uris = new List<Uri>();
if (!domainUris.Any())
{
return domainUris.Select(domainUri => new Uri(domainUri.GetLeftPart(UriPartial.Path).TrimEnd('/') + path));
// no domain was found : return an absolute or relative url
// handle vdir if any
if (current == null)
uris.Add(new Uri(UriUtility.ToAbsolute(path), UriKind.Relative));
else
uris.Add(new Uri(current.GetLeftPart(UriPartial.Authority) + UriUtility.ToAbsolute(path)));
}
else
{
// no domain was found : return a relative url, add vdir if any
return new Uri[] { new Uri(SystemDirectories.Root + path, UriKind.Relative) };
// domains were found : return -- FIXME?
uris.AddRange(domainUris.Select(domainUri => new Uri(domainUri.GetLeftPart(UriPartial.Path).TrimEnd('/') + path)));
}
return uris.Select(uri => UriUtility.UriFromUmbraco(uri));
}
Uri DomainUriAtNode(int nodeId, Uri current)
@@ -263,6 +302,28 @@ namespace Umbraco.Web.Routing
return domainAndUris.Select(d => d.Uri);
}
void ApplyHideTopLevelNodeFromPath(Core.Models.IDocument node, List<string> pathParts)
{
// in theory if hideTopLevelNodeFromPath is true, then there should be only once
// top-level node, or else domains should be assigned. but for backward compatibility
// we add this check - we look for the document matching "/" and if it's not us, then
// we do not hide the top level path
// it has to be taken care of in IPublishedContentStore.GetDocumentByRoute too so if
// "/foo" fails (looking for "/*/foo") we try also "/foo".
// this does not make much sense anyway esp. if both "/foo/" and "/bar/foo" exist, but
// that's the way it works pre-4.10 and we try to be backward compat for the time being
if (node.Parent == null)
{
var rootNode = _publishedContentStore.GetDocumentByRoute(_umbracoContext, "/", true);
if (rootNode.Id == node.Id) // remove only if we're the default node
pathParts.RemoveAt(pathParts.Count - 1);
}
else
{
pathParts.RemoveAt(pathParts.Count - 1);
}
}
#endregion
}
}

View File

@@ -317,7 +317,7 @@ namespace Umbraco.Web
public string NiceUrlWithDomain(int nodeId)
{
var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider;
return niceUrlsProvider.GetNiceUrl(nodeId, UmbracoContext.Current.UmbracoUrl, true);
return niceUrlsProvider.GetNiceUrl(nodeId, true);
}
#endregion

View File

@@ -7,47 +7,58 @@ using umbraco;
namespace Umbraco.Web
{
static class UriUtility
public static class UriUtility
{
static readonly string _appVirtualPath;
static readonly string _appVirtualPathPrefix;
static string _appPath;
static string _appPathPrefix;
static UriUtility()
{
// Virtual path
_appVirtualPath = HttpRuntime.AppDomainAppVirtualPath ?? "/";
_appVirtualPathPrefix = _appVirtualPath;
if (_appVirtualPathPrefix == "/")
_appVirtualPathPrefix = String.Empty;
SetAppDomainAppVirtualPath(HttpRuntime.AppDomainAppVirtualPath);
}
// internal for unit testing only
internal static void SetAppDomainAppVirtualPath(string appPath)
{
_appPath = appPath ?? "/";
_appPathPrefix = _appPath;
if (_appPathPrefix == "/")
_appPathPrefix = String.Empty;
}
// will be "/" or "/foo"
public static string AppVirtualPath
public static string AppPath
{
get { return _appVirtualPath; }
get { return _appPath; }
}
// will be "" or "/foo"
public static string AppVirtualPathPrefix
public static string AppPathPrefix
{
get { return _appVirtualPathPrefix; }
get { return _appPathPrefix; }
}
public static string ToAbsolute(string url)
// adds the virtual directory if any
// see also VirtualPathUtility.ToAbsolute
// FIXME
public static string ToAbsolute(string url)
{
return ResolveUrl(url);
//return ResolveUrl(url);
url = url.TrimStart('~');
return _appPathPrefix + url;
}
public static string ToAppRelative(string url)
// strips the virtual directory if any
// see also VirtualPathUtility.ToAppRelative
public static string ToAppRelative(string virtualPath)
{
if (url.StartsWith(_appVirtualPathPrefix))
url = url.Substring(_appVirtualPathPrefix.Length);
return url;
if (virtualPath.StartsWith(_appPathPrefix))
virtualPath = virtualPath.Substring(_appPathPrefix.Length);
return virtualPath;
}
// fixme - what about vdir?
// path = path.Substring(UriUtility.AppVirtualPathPrefix.Length); // remove virtual directory
// maps an internal umbraco uri to a public uri
// ie with virtual directory, .aspx if required...
public static Uri UriFromUmbraco(Uri uri)
{
var path = uri.GetSafeAbsolutePath();
@@ -59,19 +70,19 @@ namespace Umbraco.Web
else if (UmbracoSettings.AddTrailingSlash)
path += "/";
path = ToAbsolute(path);
return uri.Rewrite(path);
}
/// <summary>
/// Converts a Uri to a path based URI that is lower cased
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
public static Uri UriToUmbraco(Uri uri)
// maps a public uri to an internal umbraco uri
// ie no virtual directory, no .aspx, lowercase...
public static Uri UriToUmbraco(Uri uri)
{
var path = uri.GetSafeAbsolutePath();
path = path.ToLower();
path = ToAppRelative(path); // strip vdir if any
//we need to check if the path is /default.aspx because this will occur when using a
//web server pre IIS 7 when requesting the root document
@@ -116,7 +127,7 @@ namespace Umbraco.Web
}
StringBuilder sbUrl = new StringBuilder();
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
sbUrl.Append(_appPathPrefix);
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');
// found question mark already? query string, do not touch!

View File

@@ -20,6 +20,7 @@ using umbraco.cms.businesslogic.web;
using umbraco.presentation;
using umbraco.cms.businesslogic.skinning;
using System.Collections.Generic;
using System.Linq;
namespace umbraco.cms.presentation
{
@@ -180,7 +181,7 @@ namespace umbraco.cms.presentation
publishProps.addProperty(ui.Text("content", "expireDate", base.getUser()), dpExpire);
// url's
updateLinks();
UpdateNiceUrls();
linkProps.addProperty(ui.Text("content", "urls", base.getUser()), l);
if (domainText.Text != "")
@@ -323,7 +324,7 @@ namespace umbraco.cms.presentation
UnPublish.Visible = true;
_documentHasPublishedVersion = _document.HasPublishedVersion();
updateLinks();
UpdateNiceUrls();
}
else
{
@@ -353,57 +354,36 @@ namespace umbraco.cms.presentation
}
private void updateLinks()
{
if (_documentHasPublishedVersion)
{
// zb-00007 #29928 : refactor
string currentLink = library.NiceUrl(_document.Id);
l.Text = "<a href=\"" + currentLink + "\" target=\"_blank\">" + currentLink + "</a>";
void UpdateNiceUrls()
{
if (!_documentHasPublishedVersion)
{
l.Text = "<i>" + ui.Text("content", "itemNotPublished", base.getUser()) + "</i>";
return;
}
// domains
domainText.Text = "";
foreach (string s in _document.Path.Split(','))
{
if (int.Parse(s) > -1)
{
cms.businesslogic.web.Document dChild = new cms.businesslogic.web.Document(int.Parse(s));
if (dChild.Published)
{
cms.businesslogic.web.Domain[] domains = cms.businesslogic.web.Domain.GetDomainsById(int.Parse(s));
if (domains.Length > 0)
{
for (int i = 0; i < domains.Length; i++)
{
string tempLink = "";
if (library.NiceUrl(int.Parse(s)) == "")
tempLink = "<em>N/A</em>";
else if (int.Parse(s) != _document.Id)
{
string tempNiceUrl = library.NiceUrl(int.Parse(s));
var niceUrlProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.NiceUrlProvider;
var url = niceUrlProvider.GetNiceUrl(_document.Id);
string niceUrl = tempNiceUrl != "/" ? currentLink.Replace(tempNiceUrl.Replace(".aspx", ""), "") : currentLink;
if (!niceUrl.StartsWith("/"))
niceUrl = "/" + niceUrl;
if (url == "#")
{
var parent = _document;
while (parent.Published && parent.ParentId > 0)
parent = new Document(_document.ParentId);
if (parent.Published)
l.Text = "<i>" + ui.Text("content", "parentNotPublished", "???", base.getUser()) + "</i>";
else
l.Text = "<i>" + ui.Text("content", "parentNotPublished", parent.Text, base.getUser()) + "</i>";
return;
}
tempLink = "http://" + domains[i].Name + niceUrl;
}
else
tempLink = "http://" + domains[i].Name;
l.Text = string.Format("<a href=\"{0}\" target=\"_blank\">{0}</a>", url);
domainText.Text += "<a href=\"" + tempLink + "\" target=\"_blank\">" + tempLink + "</a><br/>";
}
}
}
else
l.Text = "<i>" + ui.Text("content", "parentNotPublished", dChild.Text, base.getUser()) + "</i>";
}
}
}
else
l.Text = "<i>" + ui.Text("content", "itemNotPublished", base.getUser()) + "</i>";
}
var lb = new System.Text.StringBuilder();
foreach (var altUrl in niceUrlProvider.GetAllAbsoluteNiceUrls(_document.Id).Where(u => u != url))
lb.AppendFormat("<a href=\"{0}\" target=\"_blank\">{0}</a><br />", altUrl);
domainText.Text = lb.ToString();
}
/// <summary>
/// Clears the page of all controls and shows a simple message. Used if users don't have visible access to the page.