From 4dc22b6ce4e8b654d57e5723c2651ea512e35ba0 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Tue, 26 Mar 2013 22:02:08 +0600 Subject: [PATCH 1/5] Applies patch for #U4-497 for getting exceptions for xslt --- src/Umbraco.Web/umbraco.presentation/macro.cs | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 80fe808478..8ff8ebffd6 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -469,7 +469,7 @@ namespace umbraco break; } case (int)MacroTypes.XSLT: - macroControl = loadMacroXSLT(this, Model, pageElements); + macroControl = LoadMacroXslt(this, Model, pageElements, true); break; case (int)MacroTypes.Script: @@ -774,21 +774,20 @@ namespace umbraco return retval; } - public Control loadMacroXSLT(macro macro, MacroModel model, Hashtable pageElements) + internal Control LoadMacroXslt(macro macro, MacroModel model, Hashtable pageElements, bool throwError) { if (XsltFile.Trim() != string.Empty) { // Get main XML - XmlDocument umbracoXML = content.Instance.XmlContent; + var umbracoXml = content.Instance.XmlContent; // Create XML document for Macro - var macroXML = new XmlDocument(); - macroXML.LoadXml(""); + var macroXml = new XmlDocument(); + macroXml.LoadXml(""); - foreach (MacroPropertyModel prop in macro.Model.Properties) + foreach (var prop in macro.Model.Properties) { - addMacroXmlNode(umbracoXML, macroXML, prop.Key, prop.Type, - prop.Value); + addMacroXmlNode(umbracoXml, macroXml, prop.Key, prop.Type, prop.Value); } if (HttpContext.Current.Request.QueryString["umbDebug"] != null && GlobalSettings.DebugMode) @@ -796,7 +795,7 @@ namespace umbraco return new LiteralControl("
Debug from " + macro.Name + - "

" + HttpContext.Current.Server.HtmlEncode(macroXML.OuterXml) + + "

" + HttpContext.Current.Server.HtmlEncode(macroXml.OuterXml) + "

"); } @@ -806,7 +805,7 @@ namespace umbraco try { - Control result = CreateControlsFromText(GetXsltTransformResult(macroXML, xsltFile)); + var result = CreateControlsFromText(GetXsltTransformResult(macroXml, xsltFile)); TraceInfo("umbracoMacro", "After performing transformation"); @@ -824,18 +823,32 @@ namespace umbraco ie = ie.InnerException; } - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - return GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour }; + var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + //if it is null, then we are supposed to throw the (original) exception + // see: http://issues.umbraco.org/issue/U4-497 at the end + if (macroControl == null && throwError) + { + throw; + } + return macroControl; } } catch (Exception e) { Exceptions.Add(e); LogHelper.WarnWithException("Error loading XSLT " + Model.Xslt, true, e); - + // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - return GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour }; + var macroControl = GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + //if it is null, then we are supposed to throw the (original) exception + // see: http://issues.umbraco.org/issue/U4-497 at the end + if (macroControl == null && throwError) + { + throw; + } + return macroControl; } } @@ -843,6 +856,11 @@ namespace umbraco return new LiteralControl(string.Empty); } + public Control loadMacroXSLT(macro macro, MacroModel model, Hashtable pageElements) + { + return LoadMacroXslt(macro, model, pageElements, false); + } + /// /// Parses the text for umbraco Item controls that need to be rendered. /// From b1fa06bfe842f30ee9193cb817cfc3f0d36e7fed Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Tue, 26 Mar 2013 22:02:49 +0600 Subject: [PATCH 2/5] Removes unused code. --- src/Umbraco.Web/umbraco.presentation/macro.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 8ff8ebffd6..3ac43525f5 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -765,15 +765,6 @@ namespace umbraco HttpRuntime.Cache.Remove("macroXslt_" + XsltFile); } - private Hashtable keysToLowerCase(Hashtable input) - { - var retval = new Hashtable(); - foreach (object key in input.Keys) - retval.Add(key.ToString().ToLower(), input[key]); - - return retval; - } - internal Control LoadMacroXslt(macro macro, MacroModel model, Hashtable pageElements, bool throwError) { if (XsltFile.Trim() != string.Empty) From 2699611ba34c052cb7dea3c8bb1b5827727eed60 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 27 Mar 2013 02:58:59 +0600 Subject: [PATCH 3/5] adds patch for #U4-1754 --- .../umbraco/uQuery/NodeExtensions.cs | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs index 7ba77ac082..0fa8461125 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Linq; using System.Xml; using umbraco.cms.businesslogic.web; +using umbraco.interfaces; using umbraco.NodeFactory; namespace umbraco @@ -19,7 +20,7 @@ namespace umbraco /// The node. /// The level. /// Returns an ancestor node by path level. - public static Node GetAncestorByPathLevel(this Node node, int level) + public static INode GetAncestorByPathLevel(this INode node, int level) { var nodeId = uQuery.GetNodeIdByPathLevel(node.Path, level); return uQuery.GetNode(nodeId); @@ -31,13 +32,13 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable - public static IEnumerable GetAncestorNodes(this Node node) + public static IEnumerable GetAncestorNodes(this INode node) { var ancestor = node.Parent; while (ancestor != null) { - yield return ancestor as Node; + yield return ancestor as INode; ancestor = ancestor.Parent; } @@ -48,7 +49,7 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable - public static IEnumerable GetAncestorOrSelfNodes(this Node node) + public static IEnumerable GetAncestorOrSelfNodes(this INode node) { yield return node; @@ -63,11 +64,11 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable - public static IEnumerable GetPrecedingSiblingNodes(this Node node) + public static IEnumerable GetPrecedingSiblingNodes(this INode node) { if (node.Parent != null) { - var parentNode = node.Parent as Node; + var parentNode = node.Parent as INode; foreach (var precedingSiblingNode in parentNode.GetChildNodes().Where(childNode => childNode.SortOrder < node.SortOrder)) { yield return precedingSiblingNode; @@ -80,11 +81,11 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable - public static IEnumerable GetFollowingSiblingNodes(this Node node) + public static IEnumerable GetFollowingSiblingNodes(this INode node) { if (node.Parent != null) { - var parentNode = node.Parent as Node; + var parentNode = node.Parent as INode; foreach (var followingSiblingNode in parentNode.GetChildNodes().Where(childNode => childNode.SortOrder > node.SortOrder)) { yield return followingSiblingNode; @@ -97,11 +98,11 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable - public static IEnumerable GetSiblingNodes(this Node node) + public static IEnumerable GetSiblingNodes(this INode node) { if (node.Parent != null) { - var parentNode = node.Parent as Node; + var parentNode = node.Parent as INode; foreach (var siblingNode in parentNode.GetChildNodes().Where(childNode => childNode.Id != node.Id)) { yield return siblingNode; @@ -114,7 +115,7 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable - public static IEnumerable GetDescendantOrSelfNodes(this Node node) + public static IEnumerable GetDescendantOrSelfNodes(this INode node) { yield return node; @@ -131,9 +132,9 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable - public static IEnumerable GetDescendantNodes(this Node node) + public static IEnumerable GetDescendantNodes(this INode node) { - foreach (Node child in node.Children) + foreach (INode child in node.ChildrenAsList) { yield return child; @@ -151,9 +152,9 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The func /// Nodes as IEnumerable - public static IEnumerable GetDescendantNodes(this Node node, Func func) + public static IEnumerable GetDescendantNodes(this INode node, Func func) { - foreach (Node child in node.Children) + foreach (INode child in node.ChildrenAsList) { if (func(child)) { @@ -174,7 +175,7 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The document type alias. /// Nodes as IEnumerable - public static IEnumerable GetDescendantNodesByType(this Node node, string documentTypeAlias) + public static IEnumerable GetDescendantNodesByType(this INode node, string documentTypeAlias) { return node.GetDescendantNodes().Where(x => x.NodeTypeAlias == documentTypeAlias); } @@ -187,9 +188,9 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable - public static IEnumerable GetChildNodes(this Node node) + public static IEnumerable GetChildNodes(this INode node) { - foreach (Node child in node.Children) + foreach (INode child in node.ChildrenAsList) { yield return child; } @@ -201,9 +202,9 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The func. /// Nodes as IEnumerable - public static IEnumerable GetChildNodes(this Node node, Func func) + public static IEnumerable GetChildNodes(this INode node, Func func) { - foreach (Node child in node.Children) + foreach (Node child in node.ChildrenAsList) { if (func(child)) { @@ -218,7 +219,7 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The document type alias. /// Nodes as IEnumerable - public static IEnumerable GetChildNodesByType(this Node node, string documentTypeAlias) + public static IEnumerable GetChildNodesByType(this INode node, string documentTypeAlias) { return node.GetChildNodes(n => n.NodeTypeAlias == documentTypeAlias); } @@ -229,11 +230,11 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// name of node to search for /// null or Node - public static Node GetChildNodeByName(this Node parentNode, string nodeName) + public static INode GetChildNodeByName(this INode parentNode, string nodeName) { - Node node = null; + INode node = null; - foreach (Node child in parentNode.Children) + foreach (INode child in parentNode.ChildrenAsList) { if (child.Name == nodeName) { @@ -255,7 +256,7 @@ namespace umbraco /// /// true if the specified node has property; otherwise, false. /// - public static bool HasProperty(this Node node, string propertyAlias) + public static bool HasProperty(this INode node, string propertyAlias) { var property = node.GetProperty(propertyAlias); return (property != null); @@ -268,7 +269,7 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of property to get /// default(T) or property cast to (T) - public static T GetProperty(this Node node, string propertyAlias) + public static T GetProperty(this INode node, string propertyAlias) { // check to see if return object handles it's own object hydration if (typeof(uQuery.IGetProperty).IsAssignableFrom(typeof(T))) @@ -342,7 +343,7 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of propety to get /// empty string, or property value as string - private static string GetPropertyAsString(this Node node, string propertyAlias) + private static string GetPropertyAsString(this INode node, string propertyAlias) { var propertyValue = string.Empty; var property = node.GetProperty(propertyAlias); @@ -361,7 +362,7 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of propety to get /// true if can cast value, else false for all other circumstances - private static bool GetPropertyAsBoolean(this Node node, string propertyAlias) + private static bool GetPropertyAsBoolean(this INode node, string propertyAlias) { var propertyValue = false; var property = node.GetProperty(propertyAlias); @@ -389,7 +390,7 @@ namespace umbraco /// /// /// - public static int Level(this Node node) + public static int Level(this INode node) { return node.Path.Split(',').Length - 1; } @@ -399,7 +400,7 @@ namespace umbraco /// /// The node. /// Returns an XmlNode for the selected Node - public static XmlNode ToXml(this Node node) + public static XmlNode ToXml(this INode node) { return ((IHasXmlNode)umbraco.library.GetXmlNodeById(node.Id.ToString()).Current).GetNode(); } @@ -411,7 +412,7 @@ namespace umbraco /// property alias /// name of crop to get url for /// emtpy string or url - public static string GetImageCropperUrl(this Node node, string propertyAlias, string cropName) + public static string GetImageCropperUrl(this INode node, string propertyAlias, string cropName) { string cropUrl = string.Empty; @@ -452,7 +453,7 @@ namespace umbraco /// alias of property to set /// value to set /// the same node object on which this is an extension method - public static Node SetProperty(this Node node, string propertyAlias, object value) + public static INode SetProperty(this INode node, string propertyAlias, object value) { var document = new Document(node.Id); @@ -467,7 +468,7 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// if true then publishes under the context of User(0), if false uses current user /// the same node object on which this is an extension method - public static Node Publish(this Node node, bool useAdminUser) + public static INode Publish(this INode node, bool useAdminUser) { var document = new Document(node.Id); @@ -483,7 +484,7 @@ namespace umbraco /// /// Returns a random node from a collection of nodes. /// - public static Node GetRandom(this IList nodes) + public static INode GetRandom(this IList nodes) { var random = umbraco.library.GetRandom(); return nodes[random.Next(0, nodes.Count)]; @@ -497,9 +498,9 @@ namespace umbraco /// /// Returns the specified number of random nodes from a collection of nodes. /// - public static IEnumerable GetRandom(this IList nodes, int numberOfItems) + public static IEnumerable GetRandom(this IList nodes, int numberOfItems) { - var output = new List(numberOfItems); + var output = new List(numberOfItems); while (output.Count < numberOfItems) { @@ -518,7 +519,7 @@ namespace umbraco /// /// The node. /// - public static string GetFullNiceUrl(this Node node) + public static string GetFullNiceUrl(this INode node) { if (!string.IsNullOrEmpty(node.NiceUrl) && node.NiceUrl[0] == '/') { @@ -534,7 +535,7 @@ namespace umbraco /// The node. /// The language. /// - public static string GetFullNiceUrl(this Node node, string language) + public static string GetFullNiceUrl(this INode node, string language) { return node.GetFullNiceUrl(language, false); } @@ -546,7 +547,7 @@ namespace umbraco /// The language. /// if set to true [SSL]. /// - public static string GetFullNiceUrl(this Node node, string language, bool ssl) + public static string GetFullNiceUrl(this INode node, string language, bool ssl) { foreach (var domain in library.GetCurrentDomains(node.Id)) { @@ -565,7 +566,7 @@ namespace umbraco /// The node. /// The domain. /// - public static string GetFullNiceUrl(this Node node, Domain domain) + public static string GetFullNiceUrl(this INode node, Domain domain) { return node.GetFullNiceUrl(domain, false); } @@ -577,7 +578,7 @@ namespace umbraco /// The domain. /// if set to true [SSL]. /// - public static string GetFullNiceUrl(this Node node, Domain domain, bool ssl) + public static string GetFullNiceUrl(this INode node, Domain domain, bool ssl) { // TODO: [OA] Document on Codeplex if (!string.IsNullOrEmpty(node.NiceUrl) && node.NiceUrl[0] == '/') From 1f40d726de3aeb81caf8b2b9c00b86f9e1c49f7f Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 27 Mar 2013 02:59:42 +0600 Subject: [PATCH 4/5] adds patch for #U4-1754 --- .../umbraco/uQuery/NodeExtensions.cs | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs index 0fa8461125..0f03615108 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs @@ -14,6 +14,17 @@ namespace umbraco /// public static class NodeExtensions { + /// + /// Gets the ancestor by path level. + /// + /// The node. + /// The level. + /// Returns an ancestor node by path level. + public static Node GetAncestorByPathLevel(this Node node, int level) + { + return (Node) GetAncestorByPathLevel((INode) node, level); + } + /// /// Gets the ancestor by path level. /// @@ -32,6 +43,17 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable + public static IEnumerable GetAncestorNodes(this Node node) + { + return (IEnumerable) GetAncestorNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'ancestor' + /// Get the Ancestor Nodes from current to root (useful for breadcrumbs) + /// + /// an umbraco.interfaces.INode object + /// INode as IEnumerable public static IEnumerable GetAncestorNodes(this INode node) { var ancestor = node.Parent; @@ -49,6 +71,16 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable + public static IEnumerable GetAncestorOrSelfNodes(this Node node) + { + return (IEnumerable) GetAncestorOrSelfNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'ancestor-or-self' + /// + /// an umbraco.interfaces.INode object + /// INode as IEnumerable public static IEnumerable GetAncestorOrSelfNodes(this INode node) { yield return node; @@ -64,6 +96,16 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable + public static IEnumerable GetPrecedingSiblingNodes(this Node node) + { + return (IEnumerable) GetPrecedingSiblingNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'preceding-sibling' + /// + /// an umbraco.interfaces.INode object + /// INode as IEumerable public static IEnumerable GetPrecedingSiblingNodes(this INode node) { if (node.Parent != null) @@ -81,6 +123,16 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable + public static IEnumerable GetFollowingSiblingNodes(this Node node) + { + return (IEnumerable) GetFollowingSiblingNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'following-sibling' + /// + /// an umbraco.interfaces.INode object + /// INode as IEumerable public static IEnumerable GetFollowingSiblingNodes(this INode node) { if (node.Parent != null) @@ -98,6 +150,16 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEumerable + public static IEnumerable GetSiblingNodes(this Node node) + { + return (IEnumerable) GetSiblingNodes((INode)node); + } + + /// + /// Gets all sibling Nodes + /// + /// an umbraco.interfaces.INode object + /// INode as IEumerable public static IEnumerable GetSiblingNodes(this INode node) { if (node.Parent != null) @@ -115,6 +177,16 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable + public static IEnumerable GetDescendantOrSelfNodes(this Node node) + { + return (IEnumerable) GetDescendantOrSelfNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'descendant-or-self' + /// + /// an umbraco.interfaces.INode object + /// INode as IEnumerable public static IEnumerable GetDescendantOrSelfNodes(this INode node) { yield return node; @@ -132,6 +204,18 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable + public static IEnumerable GetDescendantNodes(this Node node) + { + return (IEnumerable) GetDescendantNodes((INode) node); + } + + /// + /// Functionally similar to the XPath axis 'descendant' + /// Make the All Descendants LINQ queryable + /// taken from: http://our.umbraco.org/wiki/how-tos/useful-helper-extension-methods-%28linq-null-safe-access%29 + /// + /// an umbraco.interfaces.INode object + /// INode as IEnumerable public static IEnumerable GetDescendantNodes(this INode node) { foreach (INode child in node.ChildrenAsList) @@ -152,6 +236,18 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The func /// Nodes as IEnumerable + public static IEnumerable GetDescendantNodes(this Node node, Func func) + { + return (IEnumerable) GetDescendantNodes((INode)node, (Func) func); + } + + /// + /// Drills down into the descendant nodes returning those where Func is true, when Func is false further descendants are not checked + /// taken from: http://ucomponents.codeplex.com/discussions/246406 + /// + /// The umbraco.interfaces.INode. + /// The func + /// INode as IEnumerable public static IEnumerable GetDescendantNodes(this INode node, Func func) { foreach (INode child in node.ChildrenAsList) @@ -175,6 +271,18 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The document type alias. /// Nodes as IEnumerable + public static IEnumerable GetDescendantNodesByType(this Node node, string documentTypeAlias) + { + return (IEnumerable) GetDescendantNodesByType((INode)node, documentTypeAlias); + } + + /// + /// Gets the descendant nodes by document-type. + /// Get all descendants, and then return only those that match the requested typeAlias + /// + /// The umbraco.interfaces.INode. + /// The document type alias. + /// INodes as IEnumerable public static IEnumerable GetDescendantNodesByType(this INode node, string documentTypeAlias) { return node.GetDescendantNodes().Where(x => x.NodeTypeAlias == documentTypeAlias); @@ -188,6 +296,19 @@ namespace umbraco /// /// an umbraco.presentation.nodeFactory.Node object /// Node as IEnumerable + public static IEnumerable GetChildNodes(this Node node) + { + return (IEnumerable) GetChildNodes((INode)node); + } + + /// + /// Functionally similar to the XPath axis 'child' + /// Make the imediate Children LINQ queryable + /// Performance optimised for just imediate children. + /// taken from: http://our.umbraco.org/wiki/how-tos/useful-helper-extension-methods-%28linq-null-safe-access%29 + /// + /// an umbraco.interfaces.INode object + /// INode as IEnumerable public static IEnumerable GetChildNodes(this INode node) { foreach (INode child in node.ChildrenAsList) @@ -202,6 +323,17 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The func. /// Nodes as IEnumerable + public static IEnumerable GetChildNodes(this Node node, Func func) + { + return (IEnumerable) GetChildNodes((INode)node, (Func) func); + } + + /// + /// Gets the child nodes. + /// + /// The umbraco.interfaces.INode. + /// The func. + /// INodes as IEnumerable public static IEnumerable GetChildNodes(this INode node, Func func) { foreach (Node child in node.ChildrenAsList) @@ -219,6 +351,17 @@ namespace umbraco /// The umbraco.presentation.nodeFactory.Node. /// The document type alias. /// Nodes as IEnumerable + public static IEnumerable GetChildNodesByType(this Node node, string documentTypeAlias) + { + return (IEnumerable) GetChildNodesByType((INode)node, documentTypeAlias); + } + + /// + /// Gets the child nodes by document-type. + /// + /// The umbraco.interfaces.INode. + /// The document type alias. + /// INodes as IEnumerable public static IEnumerable GetChildNodesByType(this INode node, string documentTypeAlias) { return node.GetChildNodes(n => n.NodeTypeAlias == documentTypeAlias); @@ -230,6 +373,17 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// name of node to search for /// null or Node + public static Node GetChildNodeByName(this Node parentNode, string nodeName) + { + return (Node) GetChildNodeByName((INode)parentNode, nodeName); + } + + /// + /// Extension method on Node to retun a matching child node by name + /// + /// an umbraco.interfaces.INode object + /// name of node to search for + /// null or INode public static INode GetChildNodeByName(this INode parentNode, string nodeName) { INode node = null; @@ -256,6 +410,19 @@ namespace umbraco /// /// true if the specified node has property; otherwise, false. /// + public static bool HasProperty(this Node node, string propertyAlias) + { + return HasProperty((INode)node, propertyAlias); + } + + /// + /// Determines whether the specified node has property. + /// + /// The INode. + /// The property alias. + /// + /// true if the specified node has property; otherwise, false. + /// public static bool HasProperty(this INode node, string propertyAlias) { var property = node.GetProperty(propertyAlias); @@ -269,6 +436,18 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of property to get /// default(T) or property cast to (T) + public static T GetProperty(this Node node, string propertyAlias) + { + return GetProperty((INode)node, propertyAlias); + } + + /// + /// Get a value of type T from a property + /// + /// type T to cast to + /// an umbraco.interfaces.INode object + /// alias of property to get + /// default(T) or property cast to (T) public static T GetProperty(this INode node, string propertyAlias) { // check to see if return object handles it's own object hydration @@ -343,6 +522,17 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of propety to get /// empty string, or property value as string + private static string GetPropertyAsString(this Node node, string propertyAlias) + { + return GetPropertyAsString((INode)node, propertyAlias); + } + + /// + /// Get a string value for the supplied property alias + /// + /// an umbraco.interfaces.INode object + /// alias of propety to get + /// empty string, or property value as string private static string GetPropertyAsString(this INode node, string propertyAlias) { var propertyValue = string.Empty; @@ -362,6 +552,17 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// alias of propety to get /// true if can cast value, else false for all other circumstances + private static bool GetPropertyAsBoolean(this Node node, string propertyAlias) + { + return GetPropertyAsBoolean((INode)node, propertyAlias); + } + + /// + /// Get a boolean value for the supplied property alias (works with built in Yes/No dataype) + /// + /// an umbraco.interfaces.INode object + /// alias of propety to get + /// true if can cast value, else false for all other circumstances private static bool GetPropertyAsBoolean(this INode node, string propertyAlias) { var propertyValue = false; @@ -383,6 +584,18 @@ namespace umbraco return propertyValue; } + /// + /// Tell me the level of this node (0 = root) + /// updated from Depth and changed to start at 0 + /// to align with other 'Level' methods (eg xslt) + /// + /// + /// + public static int Level(this Node node) + { + return Level((INode)node); + } + /// /// Tell me the level of this node (0 = root) /// updated from Depth and changed to start at 0 @@ -400,6 +613,16 @@ namespace umbraco /// /// The node. /// Returns an XmlNode for the selected Node + public static XmlNode ToXml(this Node node) + { + return ToXml((INode) node); + } + + /// + /// Gets the XML for the Node. + /// + /// The INode. + /// Returns an XmlNode for the selected Node public static XmlNode ToXml(this INode node) { return ((IHasXmlNode)umbraco.library.GetXmlNodeById(node.Id.ToString()).Current).GetNode(); @@ -412,6 +635,18 @@ namespace umbraco /// property alias /// name of crop to get url for /// emtpy string or url + public static string GetImageCropperUrl(this Node node, string propertyAlias, string cropName) + { + return GetImageCropperUrl((INode)node, propertyAlias, cropName); + } + + /// + /// Returns the url for a given crop name using the built in Image Cropper datatype + /// + /// an umbraco.interfaces.INode object + /// property alias + /// name of crop to get url for + /// emtpy string or url public static string GetImageCropperUrl(this INode node, string propertyAlias, string cropName) { string cropUrl = string.Empty; @@ -453,6 +688,18 @@ namespace umbraco /// alias of property to set /// value to set /// the same node object on which this is an extension method + public static Node SetProperty(this Node node, string propertyAlias, object value) + { + return (Node) SetProperty((INode)node, propertyAlias, value); + } + + /// + /// Sets a property value on this node + /// + /// an umbraco.interfaces.INode object + /// alias of property to set + /// value to set + /// the same node object on which this is an extension method public static INode SetProperty(this INode node, string propertyAlias, object value) { var document = new Document(node.Id); @@ -468,6 +715,17 @@ namespace umbraco /// an umbraco.presentation.nodeFactory.Node object /// if true then publishes under the context of User(0), if false uses current user /// the same node object on which this is an extension method + public static Node Publish(this Node node, bool useAdminUser) + { + return (Node) Publish((INode)node, useAdminUser); + } + + /// + /// Republishes this node + /// + /// an umbraco.interfaces.INode object + /// if true then publishes under the context of User(0), if false uses current user + /// the same node object on which this is an extension method public static INode Publish(this INode node, bool useAdminUser) { var document = new Document(node.Id); @@ -484,6 +742,18 @@ namespace umbraco /// /// Returns a random node from a collection of nodes. /// + public static Node GetRandom(this IList nodes) + { + return GetRandom(nodes); + } + + /// + /// Gets a random node. + /// + /// The nodes. + /// + /// Returns a random INode from a collection of INodes. + /// public static INode GetRandom(this IList nodes) { var random = umbraco.library.GetRandom(); @@ -498,6 +768,19 @@ namespace umbraco /// /// Returns the specified number of random nodes from a collection of nodes. /// + public static IEnumerable GetRandom(this IList nodes, int numberOfItems) + { + return GetRandom(nodes, numberOfItems); + } + + /// + /// Gets a collection of random nodes. + /// + /// The nodes. + /// The number of items. + /// + /// Returns the specified number of random INodes from a collection of INodes. + /// public static IEnumerable GetRandom(this IList nodes, int numberOfItems) { var output = new List(numberOfItems); @@ -519,6 +802,16 @@ namespace umbraco /// /// The node. /// + public static string GetFullNiceUrl(this Node node) + { + return GetFullNiceUrl((INode)node); + } + + /// + /// Gets the full nice URL. + /// + /// The node as INode. + /// public static string GetFullNiceUrl(this INode node) { if (!string.IsNullOrEmpty(node.NiceUrl) && node.NiceUrl[0] == '/') @@ -535,6 +828,17 @@ namespace umbraco /// The node. /// The language. /// + public static string GetFullNiceUrl(this Node node, string language) + { + return GetFullNiceUrl((INode)node, language); + } + + /// + /// Gets the full nice URL. + /// + /// The node as INode. + /// The language. + /// public static string GetFullNiceUrl(this INode node, string language) { return node.GetFullNiceUrl(language, false); @@ -547,6 +851,18 @@ namespace umbraco /// The language. /// if set to true [SSL]. /// + public static string GetFullNiceUrl(this Node node, string langauge, bool ssl) + { + return GetFullNiceUrl((INode)node, langauge, ssl); + } + + /// + /// Gets the full nice URL. + /// + /// The node as INode. + /// The language. + /// if set to true [SSL]. + /// public static string GetFullNiceUrl(this INode node, string language, bool ssl) { foreach (var domain in library.GetCurrentDomains(node.Id)) @@ -566,6 +882,17 @@ namespace umbraco /// The node. /// The domain. /// + public static string GetFullNiceUrl(this Node node, Domain domain) + { + return GetFullNiceUrl((INode)node, domain); + } + + /// + /// Gets the full nice URL. + /// + /// The node as INode. + /// The domain. + /// public static string GetFullNiceUrl(this INode node, Domain domain) { return node.GetFullNiceUrl(domain, false); @@ -578,6 +905,18 @@ namespace umbraco /// The domain. /// if set to true [SSL]. /// + public static string GetFullNiceUrl(this Node node, Domain domain, bool ssl) + { + return GetFullNiceUrl((INode)node, domain, ssl); + } + + /// + /// Gets the full nice URL. + /// + /// The node as INode. + /// The domain. + /// if set to true [SSL]. + /// public static string GetFullNiceUrl(this INode node, Domain domain, bool ssl) { // TODO: [OA] Document on Codeplex @@ -591,6 +930,7 @@ namespace umbraco #pragma warning disable 0618 + /// /// Converts legacy nodeFactory collection to INode collection /// From 9452d5fd097ef0c452bc02f0703372c2ad6d2c88 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 27 Mar 2013 03:08:37 +0600 Subject: [PATCH 5/5] adds patch for #U4-1754 and updates --- .../umbraco/uQuery/NodeExtensions.cs | 59 ++++++++----------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs index 0f03615108..b14b1380ce 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/NodeExtensions.cs @@ -45,7 +45,7 @@ namespace umbraco /// Node as IEnumerable public static IEnumerable GetAncestorNodes(this Node node) { - return (IEnumerable) GetAncestorNodes((INode)node); + return GetAncestorNodes((INode)node).Cast(); } /// @@ -73,7 +73,7 @@ namespace umbraco /// Node as IEnumerable public static IEnumerable GetAncestorOrSelfNodes(this Node node) { - return (IEnumerable) GetAncestorOrSelfNodes((INode)node); + return GetAncestorOrSelfNodes((INode)node).Cast(); } /// @@ -98,7 +98,7 @@ namespace umbraco /// Node as IEumerable public static IEnumerable GetPrecedingSiblingNodes(this Node node) { - return (IEnumerable) GetPrecedingSiblingNodes((INode)node); + return GetPrecedingSiblingNodes((INode)node).Cast(); } /// @@ -125,7 +125,7 @@ namespace umbraco /// Node as IEumerable public static IEnumerable GetFollowingSiblingNodes(this Node node) { - return (IEnumerable) GetFollowingSiblingNodes((INode)node); + return GetFollowingSiblingNodes((INode)node).Cast(); } /// @@ -152,7 +152,7 @@ namespace umbraco /// Node as IEumerable public static IEnumerable GetSiblingNodes(this Node node) { - return (IEnumerable) GetSiblingNodes((INode)node); + return GetSiblingNodes((INode)node).Cast(); } /// @@ -179,7 +179,7 @@ namespace umbraco /// Node as IEnumerable public static IEnumerable GetDescendantOrSelfNodes(this Node node) { - return (IEnumerable) GetDescendantOrSelfNodes((INode)node); + return GetDescendantOrSelfNodes((INode)node).Cast(); } /// @@ -206,7 +206,7 @@ namespace umbraco /// Node as IEnumerable public static IEnumerable GetDescendantNodes(this Node node) { - return (IEnumerable) GetDescendantNodes((INode) node); + return GetDescendantNodes((INode) node).Cast(); } /// @@ -238,7 +238,7 @@ namespace umbraco /// Nodes as IEnumerable public static IEnumerable GetDescendantNodes(this Node node, Func func) { - return (IEnumerable) GetDescendantNodes((INode)node, (Func) func); + return GetDescendantNodes((INode)node, (Func) func).Cast(); } /// @@ -273,7 +273,7 @@ namespace umbraco /// Nodes as IEnumerable public static IEnumerable GetDescendantNodesByType(this Node node, string documentTypeAlias) { - return (IEnumerable) GetDescendantNodesByType((INode)node, documentTypeAlias); + return GetDescendantNodesByType((INode)node, documentTypeAlias).Cast(); } /// @@ -298,7 +298,7 @@ namespace umbraco /// Node as IEnumerable public static IEnumerable GetChildNodes(this Node node) { - return (IEnumerable) GetChildNodes((INode)node); + return GetChildNodes((INode)node).Cast(); } /// @@ -311,10 +311,7 @@ namespace umbraco /// INode as IEnumerable public static IEnumerable GetChildNodes(this INode node) { - foreach (INode child in node.ChildrenAsList) - { - yield return child; - } + return node.ChildrenAsList; } /// @@ -325,7 +322,7 @@ namespace umbraco /// Nodes as IEnumerable public static IEnumerable GetChildNodes(this Node node, Func func) { - return (IEnumerable) GetChildNodes((INode)node, (Func) func); + return GetChildNodes((INode)node, (Func) func).Cast(); } /// @@ -334,9 +331,9 @@ namespace umbraco /// The umbraco.interfaces.INode. /// The func. /// INodes as IEnumerable - public static IEnumerable GetChildNodes(this INode node, Func func) + public static IEnumerable GetChildNodes(this INode node, Func func) { - foreach (Node child in node.ChildrenAsList) + foreach (INode child in node.ChildrenAsList) { if (func(child)) { @@ -353,7 +350,7 @@ namespace umbraco /// Nodes as IEnumerable public static IEnumerable GetChildNodesByType(this Node node, string documentTypeAlias) { - return (IEnumerable) GetChildNodesByType((INode)node, documentTypeAlias); + return GetChildNodesByType((INode)node, documentTypeAlias).Cast(); } /// @@ -386,20 +383,7 @@ namespace umbraco /// null or INode public static INode GetChildNodeByName(this INode parentNode, string nodeName) { - INode node = null; - - foreach (INode child in parentNode.ChildrenAsList) - { - if (child.Name == nodeName) - { - node = child; - break; - } - } - - return node; - - //// return node.GetChildNodes(n => n.Name == nodeName); + return parentNode.ChildrenAsList.FirstOrDefault(child => child.Name == nodeName); } /// @@ -462,6 +446,8 @@ namespace umbraco return (T)t; } + //TODO: This should be converted to our extension method TryConvertTo .... + var typeConverter = TypeDescriptor.GetConverter(typeof(T)); if (typeConverter != null) { @@ -744,7 +730,7 @@ namespace umbraco /// public static Node GetRandom(this IList nodes) { - return GetRandom(nodes); + return (Node)GetRandom(nodes.Cast().ToList()); } /// @@ -770,7 +756,8 @@ namespace umbraco /// public static IEnumerable GetRandom(this IList nodes, int numberOfItems) { - return GetRandom(nodes, numberOfItems); + var randomNodes = GetRandom(nodes.Cast().ToList(), numberOfItems); + return randomNodes.Cast().ToList(); } /// @@ -851,9 +838,9 @@ namespace umbraco /// The language. /// if set to true [SSL]. /// - public static string GetFullNiceUrl(this Node node, string langauge, bool ssl) + public static string GetFullNiceUrl(this Node node, string language, bool ssl) { - return GetFullNiceUrl((INode)node, langauge, ssl); + return GetFullNiceUrl((INode)node, language, ssl); } ///