Merge pull request #2656 from umbraco/temp8-U4-11378

U4-11378 - ContentFinderByUrlAlias
This commit is contained in:
Claus
2018-06-01 08:30:46 +02:00
committed by GitHub

View File

@@ -56,42 +56,45 @@ namespace Umbraco.Web.Routing
// the alias may be "foo/bar" or "/foo/bar"
// there may be spaces as in "/foo/bar, /foo/nil"
// these should probably be taken care of earlier on
// these should probably be taken care of earlier on
// TODO
// can we normalize the values so that they contain no whitespaces, and no leading slashes?
// and then the comparisons in IsMatch can be way faster - and allocate way less strings
alias = alias.TrimStart('/');
var xpathBuilder = new StringBuilder();
xpathBuilder.Append(XPathStrings.Root);
const string propertyAlias = "umbracoUrlAlias";
var test1 = alias.TrimStart('/') + ",";
var test2 = ",/" + test1; // test2 is ",/alias,"
test1 = "," + test1; // test1 is ",alias,"
bool IsMatch(IPublishedContent c, string a1, string a2)
{
// this basically implements the original XPath query ;-(
//
// "//* [@isDoc and (" +
// "contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',{0},')" +
// " or contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',/{0},')" +
// ")]"
if (!c.HasProperty(propertyAlias)) return false;
var v = "," + c.Value<string>(propertyAlias).Replace(" ", "") + ",";
return v.Contains(a1) || v.Contains(a2);
}
if (rootNodeId > 0)
xpathBuilder.AppendFormat(XPathStrings.DescendantDocumentById, rootNodeId);
XPathVariable var = null;
if (alias.Contains('\'') || alias.Contains('"'))
{
// use a var, as escaping gets ugly pretty quickly
var = new XPathVariable("alias", alias);
alias = "$alias";
var rootNode = cache.GetById(rootNodeId);
return rootNode?.Descendants().FirstOrDefault(x => IsMatch(x, test1, test2));
}
xpathBuilder.AppendFormat(XPathStrings.DescendantDocumentByAlias, alias);
var xpath = xpathBuilder.ToString();
foreach (var rootContent in cache.GetAtRoot())
{
var c = rootContent.DescendantsOrSelf().FirstOrDefault(x => IsMatch(x, test1, test2));
if (c != null) return c;
}
// note: it's OK if var is null, will be ignored
return cache.GetSingleByXPath(xpath, var);
return null;
}
#region XPath Strings
static class XPathStrings
{
public static string Root => "/root";
public const string DescendantDocumentById = "//* [@isDoc and @id={0}]";
public const string DescendantDocumentByAlias = "//* [@isDoc and ("
+ "contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',{0},')"
+ " or contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',/{0},')"
+ ")]";
}
#endregion
}
}