Merge pull request #2656 from umbraco/temp8-U4-11378
U4-11378 - ContentFinderByUrlAlias
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user