Files
Umbraco-CMS/components/editorControls/MultiNodeTreePicker/BaseTreeExtensions.cs
2012-04-28 13:57:04 -01:00

195 lines
7.7 KiB
C#

using System;
using System.Linq;
using System.Web;
using umbraco.cms.businesslogic;
using umbraco.cms.presentation.Trees;
namespace umbraco.editorControls.MultiNodeTreePicker
{
/// <summary>
/// BaseTree extensions for MultiNodeTreePicker.
/// </summary>
public static class BaseTreeExtensions
{
internal const int NoAccessId = -123456789;
internal const int NoChildNodesId = -897987654;
/// <summary>
/// Determines if it needs to render a null tree based on the start node id and returns true if it is the case.
/// </summary>
/// <param name="tree"></param>
/// <param name="startNodeId"></param>
/// <param name="rootNode"></param>
/// <param name="app"></param>
/// <returns></returns>
internal static bool SetNullTreeRootNode(this BaseTree tree, int startNodeId, ref XmlTreeNode rootNode, string app)
{
if (startNodeId == NoAccessId)
{
rootNode = new NullTree(app).RootNode;
rootNode.Text = "You do not have permission to view this tree";
rootNode.HasChildren = false;
rootNode.Source = string.Empty;
return true;
}
if (startNodeId == NoChildNodesId)
{
rootNode = new NullTree(app).RootNode;
rootNode.Text = "[No start node found]";
rootNode.HasChildren = false;
rootNode.Source = string.Empty;
return true;
}
return false;
}
/// <summary>
/// Used to determine the start node id while taking into account a user's security
/// </summary>
/// <param name="tree"></param>
/// <param name="definedStartNode"></param>
/// <param name="userStartNode"></param>
/// <returns></returns>
internal static int GetStartNodeId(this BaseTree tree, Content definedStartNode, Content userStartNode)
{
if (userStartNode == null)
{
throw new ArgumentNullException("userStartNode");
}
//the output start node id
var determinedStartNodeId = uQuery.RootNodeId;
if (definedStartNode == null)
{
//if the defined (desired) start node is null (could not be found), return NoChildNodesId
determinedStartNodeId = NoChildNodesId;
}
else if (definedStartNode.Id == uQuery.RootNodeId)
{
//if the id is -1, then the start node is the user's start node
determinedStartNodeId = userStartNode.Id;
}
else if (definedStartNode.Path.Split(',').Contains(userStartNode.Id.ToString()))
{
//If User's start node id is found in the defined path, then the start node id
//can (allowed) be the defined path.
//This should always work for administrator (-1)
determinedStartNodeId = definedStartNode.Id;
}
else if (userStartNode.Path.Split(',').Contains(definedStartNode.Id.ToString()))
{
//if the defined start node id is found in the user's path, then the start node id
//can only be the user's, not the actual start
determinedStartNodeId = userStartNode.Id;
}
else if (!definedStartNode.Path.Split(',').Contains(userStartNode.Id.ToString()))
{
//they should not have any access!
determinedStartNodeId = NoAccessId;
}
return determinedStartNodeId;
}
/// <summary>
/// Returns the data type id for the current base tree
/// </summary>
/// <remarks>
/// The data type definition id is persisted between request as a query string.
/// This is used to retreive values from the cookie which are easier persisted values
/// than trying to append everything to custom query strings.
/// </remarks>
/// <param name="tree"></param>
/// <returns></returns>
internal static int GetDataTypeId(this BaseTree tree)
{
var id = -1;
int.TryParse(tree.NodeKey, out id);
return id;
}
/// <summary>
/// return the xpath statement stored in the cookie for this control id
/// </summary>
/// <param name="tree"></param>
/// <param name="dataTypeDefId"></param>
/// <returns></returns>
internal static string GetXPathFromCookie(this BaseTree tree, int dataTypeDefId)
{
//try to read an existing cookie
var cookie = HttpContext.Current.Request.Cookies["MultiNodeTreePicker"];
if (cookie != null && cookie.Values.Count > 0)
{
return cookie.MntpGetXPathFilter(dataTypeDefId);
}
return "";
}
/// <summary>
/// Returns the xpath filter from the cookie for the current data type
/// </summary>
/// <param name="tree"></param>
/// <param name="dataTypeDefId"></param>
/// <returns></returns>
internal static XPathFilterType GetXPathFilterTypeFromCookie(this BaseTree tree, int dataTypeDefId)
{
//try to read an existing cookie
var cookie = HttpContext.Current.Request.Cookies["MultiNodeTreePicker"];
if (cookie != null && cookie.Values.Count > 0)
{
return cookie.MntpGetXPathFilterType(dataTypeDefId);
}
return XPathFilterType.Disable;
}
/// <summary>
/// Helper method to return the persisted cookied value for the tree
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tree"></param>
/// <param name="output"></param>
/// <param name="defaultVal"></param>
/// <returns></returns>
internal static T GetPersistedCookieValue<T>(this BaseTree tree, Func<HttpCookie, T> output, T defaultVal)
{
var cookie = HttpContext.Current.Request.Cookies["MultiNodeTreePicker"];
if (cookie != null && cookie.Values.Count > 0)
{
return output(cookie);
}
return defaultVal;
}
/// <summary>
/// This will return the normal service url based on id but will also ensure that the data type definition id is passed through as the nodeKey param
/// </summary>
/// <param name="tree">The tree.</param>
/// <param name="id">The id.</param>
/// <param name="dataTypeDefId">The data type def id.</param>
/// <returns></returns>
/// <remarks>
/// We only need to set the custom source to pass in our extra NodeKey data.
/// By default the system will use one or the other: Id or NodeKey, in this case
/// we are sort of 'tricking' the system and we require both.
/// Umbraco allows you to theoretically pass in any source as long as it meets the standard
/// which means you can pass around any arbitrary data to your trees in the form of a query string,
/// though it's just a bit convoluted to do so.
/// </remarks>
internal static string GetTreeServiceUrlWithParams(this BaseTree tree, int id, int dataTypeDefId)
{
var url = tree.GetTreeServiceUrl(id);
//append the node key
return url + "&nodeKey=" + dataTypeDefId;
}
}
}