2012-07-20 01:04:35 +06:00
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Xml;
|
2012-08-10 13:08:47 +06:00
|
|
|
using Umbraco.Core;
|
|
|
|
|
using Umbraco.Core.Models;
|
|
|
|
|
using Umbraco.Web.Routing;
|
2012-07-20 01:04:35 +06:00
|
|
|
using umbraco;
|
2012-08-10 13:08:47 +06:00
|
|
|
using umbraco.NodeFactory;
|
2012-07-20 01:04:35 +06:00
|
|
|
using umbraco.interfaces;
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web
|
|
|
|
|
{
|
2012-08-10 13:38:02 +06:00
|
|
|
/// <summary>
|
|
|
|
|
/// An IContentStore which uses the Xml cache system to return data
|
2012-07-20 01:04:35 +06:00
|
|
|
/// </summary>
|
2012-08-17 04:27:47 +06:00
|
|
|
internal class XmlPublishedContentStore : IPublishedContentStore
|
2012-07-20 01:04:35 +06:00
|
|
|
{
|
|
|
|
|
|
2012-08-10 13:08:47 +06:00
|
|
|
private IDocument ConvertToDocument(XmlNode xmlNode)
|
|
|
|
|
{
|
|
|
|
|
if (xmlNode == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
2012-08-10 13:19:25 +06:00
|
|
|
return new Models.XmlDocument(xmlNode);
|
2012-08-10 13:08:47 +06:00
|
|
|
}
|
2012-08-10 13:38:02 +06:00
|
|
|
|
|
|
|
|
public IDocument GetDocumentById(UmbracoContext umbracoContext, int nodeId)
|
2012-09-08 11:59:01 +07:00
|
|
|
{
|
|
|
|
|
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
|
|
|
|
|
|
|
|
|
return ConvertToDocument(GetXml(umbracoContext).GetElementById(nodeId.ToString()));
|
|
|
|
|
}
|
2012-07-20 01:04:35 +06:00
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
public IDocument GetDocumentByRoute(UmbracoContext umbracoContext, string route, bool? hideTopLevelNode = null)
|
2012-07-20 01:04:35 +06:00
|
|
|
{
|
2012-09-08 11:59:01 +07:00
|
|
|
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
|
|
|
|
if (route == null) throw new ArgumentNullException("route");
|
|
|
|
|
|
2012-08-09 07:41:13 +06:00
|
|
|
//set the default to be what is in the settings
|
|
|
|
|
if (hideTopLevelNode == null)
|
|
|
|
|
{
|
|
|
|
|
hideTopLevelNode = GlobalSettings.HideTopLevelNodeFromPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//the route always needs to be lower case because we only store the urlName attribute in lower case
|
|
|
|
|
route = route.ToLowerInvariant();
|
|
|
|
|
|
2012-07-20 01:04:35 +06:00
|
|
|
string startNodeIdString = "0";
|
|
|
|
|
string path = route;
|
|
|
|
|
if (!route.StartsWith("/"))
|
|
|
|
|
{
|
|
|
|
|
int pos = route.IndexOf('/');
|
|
|
|
|
startNodeIdString = route.Substring(0, pos);
|
|
|
|
|
path = route.Substring(pos + 1);
|
|
|
|
|
}
|
|
|
|
|
int startNodeId = int.Parse(startNodeIdString);
|
|
|
|
|
|
2012-08-09 07:41:13 +06:00
|
|
|
var xpath = CreateXpathQuery(startNodeId, path, hideTopLevelNode.Value);
|
2012-08-10 13:08:47 +06:00
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
return ConvertToDocument(GetXml(umbracoContext).SelectSingleNode(xpath));
|
2012-07-20 01:04:35 +06:00
|
|
|
}
|
|
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
public IDocument GetDocumentByUrlAlias(UmbracoContext umbracoContext, int rootNodeId, string alias)
|
2012-07-20 01:04:35 +06:00
|
|
|
{
|
2012-09-08 11:59:01 +07:00
|
|
|
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
|
|
|
|
if (alias == null) throw new ArgumentNullException("alias");
|
2012-07-20 01:04:35 +06:00
|
|
|
|
2012-09-08 11:59:01 +07:00
|
|
|
// the alias may be "foo/bar" or "/foo/bar"
|
2012-07-20 01:04:35 +06:00
|
|
|
// there may be spaces as in "/foo/bar, /foo/nil"
|
|
|
|
|
// these should probably be taken care of earlier on
|
|
|
|
|
|
|
|
|
|
alias = alias.TrimStart('/');
|
|
|
|
|
var xpathBuilder = new StringBuilder();
|
|
|
|
|
xpathBuilder.Append("/root");
|
|
|
|
|
if (rootNodeId > 0)
|
|
|
|
|
xpathBuilder.AppendFormat("//*[@isDoc and @id={0}]", rootNodeId);
|
|
|
|
|
xpathBuilder.Append("//*[@isDoc and (");
|
|
|
|
|
xpathBuilder.AppendFormat("contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',{0},')", alias);
|
|
|
|
|
xpathBuilder.AppendFormat(" or contains(concat(',',translate(umbracoUrlAlias, ' ', ''),','),',/{0},')", alias);
|
|
|
|
|
xpathBuilder.Append(")]");
|
|
|
|
|
|
|
|
|
|
var xpath = xpathBuilder.ToString();
|
|
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
return ConvertToDocument(GetXml(umbracoContext).SelectSingleNode(xpath));
|
2012-07-20 01:04:35 +06:00
|
|
|
}
|
|
|
|
|
|
2012-08-10 13:08:47 +06:00
|
|
|
//public IDocument GetNodeParent(IDocument node)
|
|
|
|
|
//{
|
|
|
|
|
// return node.Parent;
|
|
|
|
|
//}
|
|
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
public string GetDocumentProperty(UmbracoContext umbracoContext, IDocument node, string propertyAlias)
|
2012-09-08 11:59:01 +07:00
|
|
|
{
|
|
|
|
|
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
|
|
|
|
if (node == null) throw new ArgumentNullException("node");
|
|
|
|
|
if (propertyAlias == null) throw new ArgumentNullException("propertyAlias");
|
|
|
|
|
|
|
|
|
|
if (propertyAlias.StartsWith("@"))
|
2012-07-20 01:04:35 +06:00
|
|
|
{
|
2012-08-10 13:08:47 +06:00
|
|
|
//if it starts with an @ then its a property of the object, not a user defined property
|
|
|
|
|
var propName = propertyAlias.TrimStart('@');
|
2012-08-10 13:55:22 +06:00
|
|
|
var prop = TypeHelper.GetProperty(typeof(IDocument), propName, true, false, false, false);
|
2012-08-10 13:08:47 +06:00
|
|
|
if (prop == null)
|
|
|
|
|
throw new ArgumentException("The property name " + propertyAlias + " was not found on type " + typeof(IDocument));
|
2012-08-10 13:55:22 +06:00
|
|
|
var val = prop.GetValue(node, null);
|
|
|
|
|
var valAsString = val == null ? "" : val.ToString();
|
|
|
|
|
return valAsString;
|
2012-07-20 01:04:35 +06:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-08-10 13:08:47 +06:00
|
|
|
var prop = node.GetProperty(propertyAlias);
|
2012-08-17 14:02:29 +06:00
|
|
|
return prop == null ? null : Convert.ToString(prop.Value);
|
2012-08-10 13:08:47 +06:00
|
|
|
//var propertyNode = node.SelectSingleNode("./" + propertyAlias);
|
|
|
|
|
//return propertyNode == null ? null : propertyNode.InnerText;
|
2012-07-20 01:04:35 +06:00
|
|
|
}
|
2012-09-08 11:59:01 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XmlDocument GetXml(UmbracoContext umbracoContext)
|
|
|
|
|
{
|
|
|
|
|
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
2012-07-20 01:04:35 +06:00
|
|
|
|
2012-08-10 13:38:02 +06:00
|
|
|
return umbracoContext.GetXml();
|
2012-09-08 11:59:01 +07:00
|
|
|
}
|
2012-07-20 01:04:35 +06:00
|
|
|
|
2012-09-08 11:59:01 +07:00
|
|
|
static readonly char[] SlashChar = new char[] { '/' };
|
2012-07-20 01:04:35 +06:00
|
|
|
|
|
|
|
|
protected string CreateXpathQuery(int startNodeId, string path, bool hideTopLevelNodeFromPath)
|
|
|
|
|
{
|
|
|
|
|
string xpath;
|
|
|
|
|
|
|
|
|
|
if (path == string.Empty || path == "/")
|
|
|
|
|
{
|
|
|
|
|
// if url is empty
|
|
|
|
|
if (startNodeId > 0)
|
|
|
|
|
{
|
|
|
|
|
// if in a domain then use the root node of the domain
|
|
|
|
|
xpath = string.Format("/root//*[@isDoc and @id={0}]", startNodeId);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// if not in a domain - what is the default page?
|
|
|
|
|
// let's say it is the first one in the tree, if any
|
2012-07-30 22:52:59 +06:00
|
|
|
xpath = "(/root/*[@isDoc])[1]";
|
2012-07-20 01:04:35 +06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// if url is not empty, then use it to try lookup a matching page
|
|
|
|
|
var urlParts = path.Split(SlashChar, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
var xpathBuilder = new StringBuilder();
|
|
|
|
|
int partsIndex = 0;
|
|
|
|
|
|
|
|
|
|
xpathBuilder.Append("/root");
|
2012-08-07 21:40:34 +06:00
|
|
|
|
2012-07-20 01:04:35 +06:00
|
|
|
if (startNodeId == 0)
|
|
|
|
|
{
|
|
|
|
|
if (hideTopLevelNodeFromPath)
|
|
|
|
|
xpathBuilder.Append("/*[@isDoc]"); // first node is not in the url
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
xpathBuilder.AppendFormat("//*[@isDoc and @id={0}]", startNodeId);
|
|
|
|
|
if (!hideTopLevelNodeFromPath)
|
|
|
|
|
xpathBuilder.AppendFormat("[@urlName='{0}']", urlParts[partsIndex++]); // first node is in the url
|
|
|
|
|
}
|
|
|
|
|
while (partsIndex < urlParts.Length)
|
|
|
|
|
xpathBuilder.AppendFormat("/*[@isDoc and @urlName='{0}']", urlParts[partsIndex++]);
|
|
|
|
|
|
|
|
|
|
xpath = xpathBuilder.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xpath;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|