2010-12-08 07:09:45 +00:00
using System ;
using System.Collections.Generic ;
using System.Dynamic ;
using System.Linq ;
2011-02-27 12:13:04 -01:00
using System.Web ;
2010-12-08 07:09:45 +00:00
using umbraco.interfaces ;
2011-01-25 22:24:40 -13:00
using System.Collections ;
using System.Reflection ;
2011-01-27 15:29:38 -13:00
using umbraco.cms.businesslogic.web ;
using umbraco.cms.businesslogic.propertytype ;
using umbraco.cms.businesslogic.property ;
2011-02-07 14:10:38 -13:00
using umbraco.BusinessLogic ;
using umbraco.DataLayer ;
2011-02-17 14:23:20 -13:00
using umbraco.cms.businesslogic ;
2011-02-19 20:05:02 -13:00
using System.Xml ;
2011-02-19 21:19:45 -13:00
using System.Xml.Linq ;
2011-06-11 22:15:01 -02:00
using umbraco.cms.businesslogic.media ;
2011-06-12 08:23:10 -02:00
using umbraco.MacroEngines.Library ;
2011-06-19 08:19:11 -02:00
using umbraco.BusinessLogic.Utils ;
2010-12-08 07:09:45 +00:00
2011-01-28 14:36:13 -13:00
2011-05-21 14:34:46 -12:00
2010-12-08 07:09:45 +00:00
namespace umbraco.MacroEngines
{
2011-06-11 22:15:01 -02:00
public class DynamicNode : DynamicObject
2010-12-08 07:09:45 +00:00
{
2011-02-27 12:13:04 -01:00
#region consts
// these are private readonlys as const can't be Guids
private readonly Guid DATATYPE_YESNO_GUID = new Guid ( "38b352c1-e9f8-4fd8-9324-9a2eab06d97a" ) ;
private readonly Guid DATATYPE_TINYMCE_GUID = new Guid ( "5e9b75ae-face-41c8-b47e-5f4b0fd82f83" ) ;
2011-07-21 12:18:58 -12:00
//private readonly Guid DATATYPE_UCOMPONENTS_MNTP_GUID = new Guid("c2d6894b-e788-4425-bcf2-308568e3d38b");
private readonly Guid DATATYPE_DATETIMEPICKER_GUID = new Guid ( "b6fb1622-afa5-4bbf-a3cc-d9672a442222" ) ;
2011-02-27 12:13:04 -01:00
#endregion
2011-06-11 22:15:01 -02:00
internal readonly DynamicBackingItem n ;
2011-01-26 08:28:16 -13:00
2011-06-11 22:15:01 -02:00
public DynamicNodeList ownerList ;
public DynamicNode ( DynamicBackingItem n )
2010-12-08 07:09:45 +00:00
{
2010-12-26 17:50:21 -11:00
if ( n ! = null )
this . n = n ;
else
throw new ArgumentNullException ( "n" , "A node must be provided to make a dynamic instance" ) ;
2010-12-08 07:09:45 +00:00
}
2011-01-27 14:22:28 -13:00
public DynamicNode ( int NodeId )
{
2011-06-11 22:15:01 -02:00
this . n = new DynamicBackingItem ( NodeId ) ;
2011-01-27 14:22:28 -13:00
}
2011-02-02 15:51:51 -13:00
public DynamicNode ( string NodeId )
{
2011-06-11 22:15:01 -02:00
int DynamicBackingItemId = 0 ;
if ( int . TryParse ( NodeId , out DynamicBackingItemId ) )
2011-02-02 15:51:51 -13:00
{
2011-06-11 22:15:01 -02:00
this . n = new DynamicBackingItem ( DynamicBackingItemId ) ;
2011-06-12 12:17:00 -02:00
return ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 12:17:00 -02:00
throw new ArgumentException ( "Cannot instantiate a DynamicNode without an id" ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-29 17:18:10 -12:00
public DynamicNode ( INode Node )
{
this . n = new DynamicBackingItem ( Node ) ;
}
2011-02-02 15:51:51 -13:00
public DynamicNode ( object NodeId )
{
2011-06-11 22:15:01 -02:00
int DynamicBackingItemId = 0 ;
if ( int . TryParse ( string . Format ( "{0}" , NodeId ) , out DynamicBackingItemId ) )
2011-02-02 15:51:51 -13:00
{
2011-06-11 22:15:01 -02:00
this . n = new DynamicBackingItem ( DynamicBackingItemId ) ;
2011-06-12 12:17:00 -02:00
return ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 12:17:00 -02:00
throw new ArgumentException ( "Cannot instantiate a DynamicNode without an id" ) ;
2011-02-02 15:51:51 -13:00
}
2011-01-25 22:24:40 -13:00
public DynamicNode ( )
{
//Empty constructor for a special case with Generic Methods
}
2011-02-24 17:19:50 -13:00
public DynamicNode Up ( )
{
return DynamicNodeWalker . Up ( this ) ;
}
public DynamicNode Up ( int number )
{
return DynamicNodeWalker . Up ( this , number ) ;
}
2011-03-08 19:42:59 -13:00
public DynamicNode Up ( string nodeTypeAlias )
{
return DynamicNodeWalker . Up ( this , nodeTypeAlias ) ;
}
2011-02-24 17:19:50 -13:00
public DynamicNode Down ( )
{
return DynamicNodeWalker . Down ( this ) ;
}
public DynamicNode Down ( int number )
{
return DynamicNodeWalker . Down ( this , number ) ;
}
2011-03-08 19:42:59 -13:00
public DynamicNode Down ( string nodeTypeAlias )
{
return DynamicNodeWalker . Down ( this , nodeTypeAlias ) ;
}
2011-02-24 17:19:50 -13:00
public DynamicNode Next ( )
{
return DynamicNodeWalker . Next ( this ) ;
}
public DynamicNode Next ( int number )
{
return DynamicNodeWalker . Next ( this , number ) ;
}
2011-03-08 19:42:59 -13:00
public DynamicNode Next ( string nodeTypeAlias )
{
return DynamicNodeWalker . Next ( this , nodeTypeAlias ) ;
}
2011-02-24 17:19:50 -13:00
public DynamicNode Previous ( )
{
return DynamicNodeWalker . Previous ( this ) ;
}
public DynamicNode Previous ( int number )
{
return DynamicNodeWalker . Previous ( this , number ) ;
}
2011-03-08 19:42:59 -13:00
public DynamicNode Previous ( string nodeTypeAlias )
{
return DynamicNodeWalker . Previous ( this , nodeTypeAlias ) ;
}
2011-03-08 19:54:55 -13:00
public DynamicNode Sibling ( int number )
{
return DynamicNodeWalker . Sibling ( this , number ) ;
}
public DynamicNode Sibling ( string nodeTypeAlias )
{
return DynamicNodeWalker . Sibling ( this , nodeTypeAlias ) ;
}
2011-02-02 11:52:09 -13:00
public DynamicNodeList GetChildrenAsList
2010-12-08 07:09:45 +00:00
{
get
{
2011-06-11 22:15:01 -02:00
List < DynamicBackingItem > children = n . ChildrenAsList ;
2011-02-20 19:55:06 -13:00
//testing
if ( children . Count = = 0 & & n . Id = = 0 )
{
2011-06-11 22:15:01 -02:00
return new DynamicNodeList ( new List < DynamicBackingItem > { this . n } ) ;
2011-02-20 19:55:06 -13:00
}
2011-02-02 11:52:09 -13:00
return new DynamicNodeList ( n . ChildrenAsList ) ;
2010-12-25 22:36:12 -11:00
}
2011-01-25 22:24:40 -13:00
}
2011-02-19 20:05:02 -13:00
public DynamicNodeList XPath ( string xPath )
{
//if this DN was initialized with an underlying NodeFactory.Node
2011-06-18 15:46:34 -02:00
if ( n ! = null & & n . Type = = DynamicBackingItemType . Content )
2011-02-19 20:05:02 -13:00
{
//get the underlying xml content
XmlDocument doc = umbraco . content . Instance . XmlContent ;
if ( doc ! = null )
{
//get n as a XmlNode (to be used as the context point for the xpath)
//rather than just applying the xPath to the root node, this lets us use .. etc from the DynamicNode point
//in test mode, n.Id is 0, let this always succeed
if ( n . Id = = 0 )
{
2011-02-19 21:19:45 -13:00
List < DynamicNode > selfList = new List < DynamicNode > ( ) { this } ;
return new DynamicNodeList ( selfList ) ;
2011-02-19 20:05:02 -13:00
}
XmlNode node = doc . SelectSingleNode ( string . Format ( "//*[@id='{0}']" , n . Id ) ) ;
if ( node ! = null )
{
//got the current node (within the XmlContent instance)
XmlNodeList nodes = node . SelectNodes ( xPath ) ;
if ( nodes . Count > 0 )
{
//we got some resulting nodes
List < NodeFactory . Node > nodeFactoryNodeList = new List < NodeFactory . Node > ( ) ;
//attempt to convert each node in the set to a NodeFactory.Node
foreach ( XmlNode nodeXmlNode in nodes )
{
try
{
nodeFactoryNodeList . Add ( new NodeFactory . Node ( nodeXmlNode ) ) ;
}
catch ( Exception ) { } //swallow the exceptions - the returned nodes might not be full nodes, e.g. property
}
2011-02-20 19:55:06 -13:00
//Wanted to do this, but because we return DynamicNodeList here, the only
//common parent class is DynamicObject
//maybe some future refactoring will solve this?
//if (nodeFactoryNodeList.Count == 0)
//{
// //if the xpath resulted in a node set, but none of them could be converted to NodeFactory.Node
// XElement xElement = XElement.Parse(node.OuterXml);
// //return
// return new DynamicXml(xElement);
//}
2011-02-19 20:05:02 -13:00
//convert the NodeFactory nodelist to IEnumerable<DynamicNode> and return it as a DynamicNodeList
2011-06-29 17:18:10 -12:00
return new DynamicNodeList ( nodeFactoryNodeList . ConvertAll ( nfNode = > new DynamicNode ( ( INode ) nfNode ) ) ) ;
2011-02-19 20:05:02 -13:00
}
else
{
2011-07-14 06:47:40 -02:00
// XPath returned no nodes, return an empty DynamicNodeList
2011-07-21 12:18:58 -12:00
return new DynamicNodeList ( ) ;
}
2011-02-19 20:05:02 -13:00
}
else
{
throw new NullReferenceException ( "Couldn't locate the DynamicNode within the XmlContent" ) ;
}
}
else
{
throw new NullReferenceException ( "umbraco.content.Instance.XmlContent is null" ) ;
}
}
else
{
throw new NullReferenceException ( "DynamicNode wasn't initialized with an underlying NodeFactory.Node" ) ;
}
}
2011-02-25 00:51:41 -13:00
public bool HasProperty ( string name )
{
if ( n ! = null )
{
try
{
IProperty prop = n . GetProperty ( name ) ;
if ( prop = = null )
{
// check for nicer support of Pascal Casing EVEN if alias is camelCasing:
if ( prop = = null & & name . Substring ( 0 , 1 ) . ToUpper ( ) = = name . Substring ( 0 , 1 ) )
{
prop = n . GetProperty ( name . Substring ( 0 , 1 ) . ToLower ( ) + name . Substring ( ( 1 ) ) ) ;
}
}
return ( prop ! = null ) ;
}
catch ( Exception )
{
return false ;
}
}
return false ;
}
2011-03-22 18:02:32 -13:00
public override bool TryInvokeMember ( InvokeMemberBinder binder , object [ ] args , out object result )
{
try
{
//Property?
result = typeof ( DynamicNode ) . InvokeMember ( binder . Name ,
System . Reflection . BindingFlags . Instance |
System . Reflection . BindingFlags . Public |
System . Reflection . BindingFlags . NonPublic |
System . Reflection . BindingFlags . GetProperty ,
null ,
this ,
args ) ;
return true ;
}
catch ( MissingMethodException )
{
try
{
//Static or Instance Method?
result = typeof ( DynamicNode ) . InvokeMember ( binder . Name ,
System . Reflection . BindingFlags . Instance |
System . Reflection . BindingFlags . Public |
System . Reflection . BindingFlags . NonPublic |
System . Reflection . BindingFlags . Static |
System . Reflection . BindingFlags . InvokeMethod ,
null ,
this ,
args ) ;
return true ;
}
catch ( MissingMethodException )
{
try
{
result = ExecuteExtensionMethod ( args , binder . Name , false ) ;
return true ;
}
catch ( TargetInvocationException )
{
result = new DynamicNull ( ) ;
return true ;
}
catch
{
result = null ;
return false ;
}
}
}
catch
{
result = null ;
return false ;
}
}
private object ExecuteExtensionMethod ( object [ ] args , string name , bool argsContainsThis )
{
object result = null ;
MethodInfo methodToExecute = ExtensionMethodFinder . FindExtensionMethod ( typeof ( IEnumerable < DynamicNode > ) , args , name , false ) ;
if ( methodToExecute = = null )
{
methodToExecute = ExtensionMethodFinder . FindExtensionMethod ( typeof ( DynamicNodeList ) , args , name , false ) ;
}
if ( methodToExecute ! = null )
{
var genericArgs = ( new [ ] { this } ) . Concat ( args ) ;
result = methodToExecute . Invoke ( null , genericArgs . ToArray ( ) ) ;
}
else
{
throw new MissingMethodException ( ) ;
}
if ( result ! = null )
{
2011-06-11 22:15:01 -02:00
if ( result is IEnumerable < DynamicBackingItem > )
2011-03-22 18:02:32 -13:00
{
2011-06-11 22:15:01 -02:00
result = new DynamicNodeList ( ( IEnumerable < DynamicBackingItem > ) result ) ;
2011-03-22 18:02:32 -13:00
}
if ( result is IEnumerable < DynamicNode > )
{
result = new DynamicNodeList ( ( IEnumerable < DynamicNode > ) result ) ;
}
2011-06-11 22:15:01 -02:00
if ( result is DynamicBackingItem )
2011-03-22 18:02:32 -13:00
{
2011-06-11 22:15:01 -02:00
result = new DynamicNode ( ( DynamicBackingItem ) result ) ;
2011-03-22 18:02:32 -13:00
}
}
return result ;
}
2011-06-11 22:15:01 -02:00
private List < string > GetAncestorOrSelfNodeTypeAlias ( DynamicBackingItem node )
2011-05-21 14:34:46 -12:00
{
List < string > list = new List < string > ( ) ;
if ( node ! = null )
{
2011-06-12 06:40:18 -02:00
if ( node . Type = = DynamicBackingItemType . Content )
2011-05-21 14:34:46 -12:00
{
2011-06-12 06:40:18 -02:00
//find the doctype node, so we can walk it's parent's tree- not the working.parent content tree
CMSNode working = ContentType . GetByAlias ( node . NodeTypeAlias ) ;
while ( working ! = null )
2011-05-21 14:34:46 -12:00
{
2011-06-12 06:40:18 -02:00
if ( ( working as ContentType ) ! = null )
{
list . Add ( ( working as ContentType ) . Alias ) ;
}
2011-06-12 13:34:15 -02:00
try
{
working = working . Parent ;
}
catch ( ArgumentException )
{
break ;
}
2011-05-21 14:34:46 -12:00
}
2011-06-12 06:40:18 -02:00
}
else
{
return null ;
2011-05-21 14:34:46 -12:00
}
}
return list ;
}
2011-06-19 08:19:11 -02:00
static Dictionary < Guid , Type > RazorDataTypeModelTypes = null ;
2011-01-25 22:24:40 -13:00
public override bool TryGetMember ( GetMemberBinder binder , out object result )
{
var name = binder . Name ;
2011-02-27 22:55:50 -13:00
result = null ; //this will never be returned
2011-01-25 22:24:40 -13:00
if ( name = = "ChildrenAsList" | | name = = "Children" )
2010-12-26 17:50:21 -11:00
{
2011-01-25 22:24:40 -13:00
result = GetChildrenAsList ;
2010-12-26 17:50:21 -11:00
return true ;
}
2011-02-27 22:55:50 -13:00
bool propertyExists = false ;
2011-01-25 22:24:40 -13:00
if ( n ! = null )
2010-12-08 07:09:45 +00:00
{
2011-07-02 17:29:47 -12:00
bool recursive = false ;
if ( name . StartsWith ( "_" ) )
{
name = name . Substring ( 1 , name . Length - 1 ) ;
recursive = true ;
}
var data = n . GetProperty ( name , recursive , out propertyExists ) ;
2011-01-25 22:24:40 -13:00
// check for nicer support of Pascal Casing EVEN if alias is camelCasing:
2011-02-27 22:55:50 -13:00
if ( data = = null & & name . Substring ( 0 , 1 ) . ToUpper ( ) = = name . Substring ( 0 , 1 ) & & ! propertyExists )
2011-01-25 22:24:40 -13:00
{
2011-07-02 17:29:47 -12:00
data = n . GetProperty ( name . Substring ( 0 , 1 ) . ToLower ( ) + name . Substring ( ( 1 ) ) , recursive , out propertyExists ) ;
2011-01-25 22:24:40 -13:00
}
if ( data ! = null )
{
result = data . Value ;
2011-01-27 15:29:38 -13:00
//special casing for true/false properties
2011-02-07 14:10:38 -13:00
//int/decimal are handled by ConvertPropertyValueByDataType
2011-02-17 14:23:20 -13:00
//fallback is stringT
2011-06-29 17:36:37 -12:00
if ( n . NodeTypeAlias = = null & & data . Alias = = null )
{
throw new ArgumentNullException ( "No node alias or property alias available. Unable to look up the datatype of the property you are trying to fetch." ) ;
}
2011-07-03 09:32:29 -12:00
//contextAlias is the node which the property data was returned from
Guid dataType = ContentType . GetDataType ( data . ContextAlias , data . Alias ) ;
2011-02-07 14:10:38 -13:00
2011-06-19 08:19:11 -02:00
if ( RazorDataTypeModelTypes = = null )
{
RazorDataTypeModelTypes = new Dictionary < Guid , Type > ( ) ;
TypeFinder . FindClassesMarkedWithAttribute ( typeof ( RazorDataTypeModel ) )
. ToList ( )
. FindAll ( type = > typeof ( IRazorDataTypeModel ) . IsAssignableFrom ( type ) )
. ConvertAll ( type = >
{
RazorDataTypeModel RazorDataTypeModelAttribute = ( RazorDataTypeModel ) Attribute . GetCustomAttribute ( type , typeof ( RazorDataTypeModel ) ) ;
Guid g = RazorDataTypeModelAttribute . DataTypeEditorId ;
return new KeyValuePair < Guid , Type > ( g , type ) ;
} )
2011-07-03 10:14:04 -12:00
. ForEach ( item = >
{
if ( ! RazorDataTypeModelTypes . ContainsKey ( item . Key ) )
2011-07-03 09:32:29 -12:00
{
RazorDataTypeModelTypes . Add ( item . Key , item . Value ) ;
}
} ) ;
2011-06-19 08:19:11 -02:00
}
if ( RazorDataTypeModelTypes . ContainsKey ( dataType ) )
{
Type dataTypeType = RazorDataTypeModelTypes [ dataType ] ;
IRazorDataTypeModel razorDataTypeModel = Activator . CreateInstance ( dataTypeType , false ) as IRazorDataTypeModel ;
if ( razorDataTypeModel ! = null )
{
2011-06-30 10:32:50 -12:00
object instance = null ;
if ( razorDataTypeModel . Init ( n . Id , data . Value , out instance ) )
2011-06-19 08:19:11 -02:00
{
2011-06-30 10:32:50 -12:00
result = instance ;
2011-06-19 08:19:11 -02:00
return true ;
}
}
}
2011-02-07 14:10:38 -13:00
//convert the string value to a known type
2011-02-17 14:23:20 -13:00
return ConvertPropertyValueByDataType ( ref result , name , dataType ) ;
2011-02-07 14:10:38 -13:00
2011-01-25 22:24:40 -13:00
}
//check if the alias is that of a child type
2011-05-21 14:34:46 -12:00
2011-06-12 11:21:44 -02:00
var typeChildren = n . ChildrenAsList ;
if ( typeChildren ! = null )
{
var filteredTypeChildren = typeChildren . Where ( x = >
2011-05-21 14:34:46 -12:00
{
List < string > ancestorAliases = GetAncestorOrSelfNodeTypeAlias ( x ) ;
2011-06-12 06:40:18 -02:00
if ( ancestorAliases = = null )
{
return false ;
}
2011-05-21 14:34:46 -12:00
return ancestorAliases . Any ( alias = > alias = = name | | MakePluralName ( alias ) = = name ) ;
} ) ;
2011-06-12 11:21:44 -02:00
if ( filteredTypeChildren . Any ( ) )
{
result = new DynamicNodeList ( filteredTypeChildren ) ;
return true ;
}
2011-01-25 22:24:40 -13:00
}
try
{
result = n . GetType ( ) . InvokeMember ( binder . Name ,
System . Reflection . BindingFlags . GetProperty |
System . Reflection . BindingFlags . Instance |
System . Reflection . BindingFlags . Public |
System . Reflection . BindingFlags . NonPublic ,
null ,
n ,
null ) ;
return true ;
}
catch
{
2011-02-24 15:56:52 -13:00
//result = null;
//return false;
2011-01-25 22:24:40 -13:00
}
2010-12-08 07:09:45 +00:00
}
2011-01-25 22:24:40 -13:00
2011-02-24 15:56:52 -13:00
//if property access, type lookup and member invoke all failed
//at this point, we're going to return null
2011-02-27 21:53:45 -13:00
//instead, we return a DynamicNull - see comments in that file
2011-02-24 15:56:52 -13:00
//this will let things like Model.ChildItem work and return nothing instead of crashing
2011-02-27 22:55:50 -13:00
if ( ! propertyExists & & result = = null )
{
//.Where explictly checks for this type
//and will make it false
//which means backwards equality (&& property != true) will pass
//forwwards equality (&& property or && property == true) will fail
result = new DynamicNull ( ) ;
return true ;
}
2011-02-19 21:19:45 -13:00
return true ;
2010-12-25 22:36:12 -11:00
}
2011-02-17 14:23:20 -13:00
private bool ConvertPropertyValueByDataType ( ref object result , string name , Guid dataType )
2011-02-07 13:12:34 -13:00
{
//the resulting property is a string, but to support some of the nice linq stuff in .Where
//we should really check some more types
//boolean
2011-02-27 12:13:04 -01:00
if ( dataType = = DATATYPE_YESNO_GUID )
2011-02-07 13:12:34 -13:00
{
bool parseResult ;
2011-04-05 23:06:30 -12:00
if ( string . IsNullOrEmpty ( string . Format ( "{0}" , result ) ) )
{
result = false ;
return true ;
}
2011-02-07 13:12:34 -13:00
if ( Boolean . TryParse ( result . ToString ( ) . Replace ( "1" , "true" ) . Replace ( "0" , "false" ) , out parseResult ) )
{
result = parseResult ;
2011-04-05 23:06:30 -12:00
return true ;
2011-02-07 13:12:34 -13:00
}
}
//integer
int iResult = 0 ;
2011-07-02 17:29:47 -12:00
if ( int . TryParse ( string . Format ( "{0}" , result ) , System . Globalization . NumberStyles . Number , System . Globalization . CultureInfo . CurrentCulture , out iResult ) )
2011-02-07 13:12:34 -13:00
{
result = iResult ;
return true ;
}
//decimal
decimal dResult = 0 ;
2011-06-30 11:00:15 -12:00
if ( decimal . TryParse ( string . Format ( "{0}" , result ) , System . Globalization . NumberStyles . Number , System . Globalization . CultureInfo . CurrentCulture , out dResult ) )
2011-02-07 13:12:34 -13:00
{
result = dResult ;
return true ;
}
2011-07-21 12:18:58 -12:00
if ( dataType = = DATATYPE_DATETIMEPICKER_GUID )
2011-02-24 15:56:52 -13:00
{
2011-07-21 12:18:58 -12:00
//date
DateTime dtResult = DateTime . MinValue ;
if ( DateTime . TryParse ( string . Format ( "{0}" , result ) , out dtResult ) )
{
result = dtResult ;
return true ;
}
else
{
result = new DynamicNull ( ) ;
return true ;
}
2011-02-24 15:56:52 -13:00
}
2011-02-27 12:13:04 -01:00
// Rich text editor (return IHtmlString so devs doesn't need to decode html
if ( dataType = = DATATYPE_TINYMCE_GUID )
{
2011-07-21 20:19:54 -12:00
result = new InternalHtmlString ( result . ToString ( ) ) ;
2011-03-25 09:33:00 -13:00
return true ;
2011-02-27 12:13:04 -01:00
}
2011-02-07 13:12:34 -13:00
if ( string . Equals ( "true" , string . Format ( "{0}" , result ) , StringComparison . CurrentCultureIgnoreCase ) )
{
result = true ;
return true ;
}
if ( string . Equals ( "false" , string . Format ( "{0}" , result ) , StringComparison . CurrentCultureIgnoreCase ) )
{
result = false ;
2011-02-19 21:19:45 -13:00
return true ;
}
if ( result ! = null )
{
string sResult = string . Format ( "{0}" , result ) . Trim ( ) ;
//a really rough check to see if this may be valid xml
if ( sResult . StartsWith ( "<" ) & & sResult . EndsWith ( ">" ) & & sResult . Contains ( "/" ) )
{
2011-02-20 19:55:06 -13:00
try
2011-02-19 21:19:45 -13:00
{
2011-06-13 15:21:16 -02:00
XElement e = XElement . Parse ( DynamicXml . StripDashesInElementOrAttributeNames ( sResult ) , LoadOptions . None ) ;
2011-02-20 19:55:06 -13:00
if ( e ! = null )
{
//check that the document element is not one of the disallowed elements
//allows RTE to still return as html if it's valid xhtml
string documentElement = e . Name . LocalName ;
if ( ! UmbracoSettings . NotDynamicXmlDocumentElements . Any ( tag = >
string . Equals ( tag , documentElement , StringComparison . CurrentCultureIgnoreCase ) ) )
{
result = new DynamicXml ( e ) ;
return true ;
}
else
{
//we will just return this as a string
return true ;
}
}
}
catch ( Exception )
{
//we will just return this as a string
2011-02-19 21:19:45 -13:00
return true ;
}
2011-02-20 19:55:06 -13:00
2011-02-19 21:19:45 -13:00
}
2011-02-07 13:12:34 -13:00
}
2011-02-07 14:10:38 -13:00
return true ;
2011-02-07 13:12:34 -13:00
}
2011-06-11 22:15:01 -02:00
public DynamicNode Media ( string propertyAlias )
2011-01-27 21:38:06 -13:00
{
if ( n ! = null )
{
IProperty prop = n . GetProperty ( propertyAlias ) ;
if ( prop ! = null )
{
int mediaNodeId ;
if ( int . TryParse ( prop . Value , out mediaNodeId ) )
{
2011-06-18 15:46:34 -02:00
return razorLibrary . Value . MediaById ( mediaNodeId ) ;
2011-01-27 21:38:06 -13:00
}
}
return null ;
}
return null ;
}
2011-03-08 18:38:06 -13:00
public bool IsProtected
2011-02-24 15:56:52 -13:00
{
2011-03-08 18:38:06 -13:00
get
2011-02-24 15:56:52 -13:00
{
2011-03-08 18:38:06 -13:00
if ( n ! = null )
{
return umbraco . library . IsProtected ( n . Id , n . Path ) ;
}
return false ;
2011-02-24 15:56:52 -13:00
}
}
2011-03-08 18:38:06 -13:00
public bool HasAccess
2011-02-24 15:56:52 -13:00
{
2011-03-08 18:38:06 -13:00
get
2011-02-24 15:56:52 -13:00
{
2011-03-08 18:38:06 -13:00
if ( n ! = null )
{
return umbraco . library . HasAccess ( n . Id , n . Path ) ;
}
return true ;
2011-02-24 15:56:52 -13:00
}
}
2011-01-27 21:38:06 -13:00
public string Media ( string propertyAlias , string mediaPropertyAlias )
{
if ( n ! = null )
{
IProperty prop = n . GetProperty ( propertyAlias ) ;
2011-01-27 21:56:09 -13:00
if ( prop = = null & & propertyAlias . Substring ( 0 , 1 ) . ToUpper ( ) = = propertyAlias . Substring ( 0 , 1 ) )
{
prop = n . GetProperty ( propertyAlias . Substring ( 0 , 1 ) . ToLower ( ) + propertyAlias . Substring ( ( 1 ) ) ) ;
}
2011-01-27 21:38:06 -13:00
if ( prop ! = null )
{
int mediaNodeId ;
if ( int . TryParse ( prop . Value , out mediaNodeId ) )
{
umbraco . cms . businesslogic . media . Media media = new cms . businesslogic . media . Media ( mediaNodeId ) ;
if ( media ! = null )
{
Property mprop = media . getProperty ( mediaPropertyAlias ) ;
2011-01-27 21:56:09 -13:00
// check for nicer support of Pascal Casing EVEN if alias is camelCasing:
if ( prop = = null & & mediaPropertyAlias . Substring ( 0 , 1 ) . ToUpper ( ) = = mediaPropertyAlias . Substring ( 0 , 1 ) )
{
mprop = media . getProperty ( mediaPropertyAlias . Substring ( 0 , 1 ) . ToLower ( ) + mediaPropertyAlias . Substring ( ( 1 ) ) ) ;
}
2011-01-27 21:38:06 -13:00
if ( mprop ! = null )
{
return string . Format ( "{0}" , mprop . Value ) ;
}
}
}
}
}
return null ;
}
2010-12-26 18:05:47 -11:00
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation
private static string MakePluralName ( string name )
{
if ( ( name . EndsWith ( "x" , StringComparison . OrdinalIgnoreCase ) | | name . EndsWith ( "ch" , StringComparison . OrdinalIgnoreCase ) ) | | ( name . EndsWith ( "ss" , StringComparison . OrdinalIgnoreCase ) | | name . EndsWith ( "sh" , StringComparison . OrdinalIgnoreCase ) ) )
{
name = name + "es" ;
return name ;
}
if ( ( name . EndsWith ( "y" , StringComparison . OrdinalIgnoreCase ) & & ( name . Length > 1 ) ) & & ! IsVowel ( name [ name . Length - 2 ] ) )
{
name = name . Remove ( name . Length - 1 , 1 ) ;
name = name + "ies" ;
return name ;
}
if ( ! name . EndsWith ( "s" , StringComparison . OrdinalIgnoreCase ) )
{
name = name + "s" ;
}
return name ;
}
private static bool IsVowel ( char c )
{
switch ( c )
{
case 'O' :
case 'U' :
case 'Y' :
case 'A' :
case 'E' :
case 'I' :
case 'o' :
case 'u' :
case 'y' :
case 'a' :
case 'e' :
case 'i' :
return true ;
}
return false ;
}
2011-01-27 12:59:34 -13:00
public DynamicNode AncestorOrSelf ( )
{
2011-01-27 13:07:10 -13:00
return AncestorOrSelf ( node = > node . Level = = 1 ) ;
2011-01-27 12:59:34 -13:00
}
2011-02-27 08:55:15 -13:00
public DynamicNode AncestorOrSelf ( int level )
{
return AncestorOrSelf ( node = > node . Level = = level ) ;
}
public DynamicNode AncestorOrSelf ( string nodeTypeAlias )
{
return AncestorOrSelf ( node = > node . NodeTypeAlias = = nodeTypeAlias ) ;
}
2010-12-28 00:04:11 -11:00
public DynamicNode AncestorOrSelf ( Func < DynamicNode , bool > func )
{
var node = this ;
while ( node ! = null )
{
if ( func ( node ) ) return node ;
2011-01-27 12:59:34 -13:00
DynamicNode parent = node . Parent ;
if ( parent ! = null )
{
if ( this ! = parent )
{
node = parent ;
}
else
{
return node ;
}
}
else
{
2011-03-14 11:42:41 -01:00
return null ;
2011-01-27 12:59:34 -13:00
}
2010-12-28 00:04:11 -11:00
}
2011-01-05 11:45:28 -01:00
return node ;
2010-12-28 00:04:11 -11:00
}
2011-02-27 08:55:15 -13:00
public DynamicNodeList AncestorsOrSelf ( Func < DynamicNode , bool > func )
2011-02-23 00:16:50 -01:00
{
2011-02-27 08:55:15 -13:00
List < DynamicNode > ancestorList = new List < DynamicNode > ( ) ;
var node = this ;
ancestorList . Add ( node ) ;
while ( node ! = null )
2011-02-23 00:16:50 -01:00
{
2011-02-27 08:55:15 -13:00
if ( node . Level = = 1 ) break ;
DynamicNode parent = node . Parent ;
if ( parent ! = null )
2011-02-23 00:16:50 -01:00
{
2011-02-27 08:55:15 -13:00
if ( this ! = parent )
2011-02-23 00:16:50 -01:00
{
2011-02-27 08:55:15 -13:00
node = parent ;
if ( func ( node ) )
2011-02-23 00:16:50 -01:00
{
ancestorList . Add ( node ) ;
}
}
else
{
break ;
}
}
2011-02-27 08:55:15 -13:00
else
{
break ;
}
2011-02-23 00:16:50 -01:00
}
2011-02-27 08:55:15 -13:00
ancestorList . Reverse ( ) ;
return new DynamicNodeList ( ancestorList ) ;
2011-02-23 00:16:50 -01:00
}
2011-02-27 08:55:15 -13:00
public DynamicNodeList AncestorsOrSelf ( )
2011-02-24 15:56:52 -13:00
{
2011-02-27 08:55:15 -13:00
return AncestorsOrSelf ( n = > true ) ;
2011-02-24 15:56:52 -13:00
}
2011-02-27 08:55:15 -13:00
public DynamicNodeList AncestorsOrSelf ( string nodeTypeAlias )
2011-02-24 15:56:52 -13:00
{
2011-02-27 08:55:15 -13:00
return AncestorsOrSelf ( n = > n . NodeTypeAlias = = nodeTypeAlias ) ;
}
public DynamicNodeList AncestorsOrSelf ( int level )
{
return AncestorsOrSelf ( n = > n . Level < = level ) ;
}
public DynamicNodeList Descendants ( string nodeTypeAlias )
{
return Descendants ( p = > p . NodeTypeAlias = = nodeTypeAlias ) ;
}
public DynamicNodeList Descendants ( int level )
{
return Descendants ( p = > p . Level > = level ) ;
}
public DynamicNodeList Descendants ( )
{
return Descendants ( n = > true ) ;
}
2011-06-11 22:15:01 -02:00
public DynamicNodeList Descendants ( Func < DynamicBackingItem , bool > func )
2011-02-27 08:55:15 -13:00
{
2011-06-11 22:15:01 -02:00
var flattenedNodes = this . n . ChildrenAsList . Map ( func , ( DynamicBackingItem n ) = > { return n . ChildrenAsList ; } ) ;
return new DynamicNodeList ( flattenedNodes . ToList ( ) . ConvertAll ( DynamicBackingItem = > new DynamicNode ( DynamicBackingItem ) ) ) ;
2011-02-27 08:55:15 -13:00
}
public DynamicNodeList DescendantsOrSelf ( int level )
{
return DescendantsOrSelf ( p = > p . Level > = level ) ;
}
public DynamicNodeList DescendantsOrSelf ( string nodeTypeAlias )
{
return DescendantsOrSelf ( p = > p . NodeTypeAlias = = nodeTypeAlias ) ;
}
public DynamicNodeList DescendantsOrSelf ( )
{
return DescendantsOrSelf ( p = > true ) ;
}
2011-06-11 22:15:01 -02:00
public DynamicNodeList DescendantsOrSelf ( Func < DynamicBackingItem , bool > func )
2011-02-27 08:55:15 -13:00
{
if ( this . n ! = null )
2011-02-24 15:56:52 -13:00
{
2011-06-11 22:15:01 -02:00
var thisNode = new List < DynamicBackingItem > ( ) ;
2011-02-27 08:55:15 -13:00
if ( func ( this . n ) )
2011-02-24 15:56:52 -13:00
{
thisNode . Add ( this . n ) ;
}
2011-06-11 22:15:01 -02:00
var flattenedNodes = this . n . ChildrenAsList . Map ( func , ( DynamicBackingItem n ) = > { return n . ChildrenAsList ; } ) ;
return new DynamicNodeList ( thisNode . Concat ( flattenedNodes ) . ToList ( ) . ConvertAll ( DynamicBackingItem = > new DynamicNode ( DynamicBackingItem ) ) ) ;
2011-02-24 15:56:52 -13:00
}
2011-06-11 22:15:01 -02:00
return new DynamicNodeList ( new List < DynamicBackingItem > ( ) ) ;
2011-02-24 15:56:52 -13:00
}
2011-02-27 08:55:15 -13:00
public DynamicNodeList Ancestors ( int level )
2011-02-24 15:56:52 -13:00
{
2011-03-08 18:43:59 -13:00
return Ancestors ( n = > n . Level < = level ) ;
2011-02-27 08:55:15 -13:00
}
public DynamicNodeList Ancestors ( string nodeTypeAlias )
{
return Ancestors ( n = > n . NodeTypeAlias = = nodeTypeAlias ) ;
}
public DynamicNodeList Ancestors ( )
{
return Ancestors ( n = > true ) ;
}
public DynamicNodeList Ancestors ( Func < DynamicNode , bool > func )
{
List < DynamicNode > ancestorList = new List < DynamicNode > ( ) ;
var node = this ;
while ( node ! = null )
2011-02-24 15:56:52 -13:00
{
2011-02-27 08:55:15 -13:00
if ( node . Level = = 1 ) break ;
DynamicNode parent = node . Parent ;
if ( parent ! = null )
{
if ( this ! = parent )
{
node = parent ;
if ( func ( node ) )
{
ancestorList . Add ( node ) ;
}
}
else
{
break ;
}
}
else
{
break ;
}
2011-02-24 15:56:52 -13:00
}
2011-02-27 08:55:15 -13:00
ancestorList . Reverse ( ) ;
return new DynamicNodeList ( ancestorList ) ;
2011-02-24 15:56:52 -13:00
}
2010-12-25 22:36:12 -11:00
public DynamicNode Parent
{
2011-01-27 12:59:34 -13:00
get
{
if ( n = = null )
{
return null ;
}
if ( n . Parent ! = null )
{
return new DynamicNode ( n . Parent ) ;
}
2011-02-23 00:16:50 -01:00
if ( n ! = null & & n . Id = = 0 )
{
return this ;
}
return null ;
2011-01-27 12:59:34 -13:00
}
2010-12-25 22:36:12 -11:00
}
2011-06-11 22:15:01 -02:00
2011-06-12 08:23:10 -02:00
private Lazy < RazorLibraryCore > razorLibrary = new Lazy < RazorLibraryCore > ( ( ) = >
{
return new RazorLibraryCore ( null ) ;
} ) ;
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-01-27 14:49:56 -13:00
public DynamicNode NodeById ( int Id )
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . NodeById ( Id ) ;
2011-01-27 14:49:56 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-02-02 15:51:51 -13:00
public DynamicNode NodeById ( string Id )
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . NodeById ( Id ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-02-02 15:51:51 -13:00
public DynamicNode NodeById ( object Id )
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . NodeById ( Id ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-06-13 15:21:16 -02:00
public DynamicNodeList NodesById ( List < object > Ids )
2011-02-26 11:43:23 -13:00
{
2011-06-13 15:21:16 -02:00
return razorLibrary . Value . NodesById ( Ids ) ;
2011-02-26 11:43:23 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-06-13 15:21:16 -02:00
public DynamicNodeList NodesById ( List < int > Ids )
2011-03-12 15:19:54 -13:00
{
2011-06-13 15:21:16 -02:00
return razorLibrary . Value . NodesById ( Ids ) ;
2011-03-12 15:19:54 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.NodeById is obsolute, use @Library.NodeById")]
2011-06-13 15:21:16 -02:00
public DynamicNodeList NodesById ( params object [ ] Ids )
2011-02-26 11:43:23 -13:00
{
2011-06-13 15:21:16 -02:00
return razorLibrary . Value . NodesById ( Ids ) ;
2011-02-26 11:43:23 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNode MediaById ( int Id )
2011-02-02 15:51:51 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Id ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNode MediaById ( string Id )
2011-02-02 15:51:51 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Id ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNode MediaById ( object Id )
2011-02-02 15:51:51 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Id ) ;
2011-02-02 15:51:51 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNodeList MediaById ( List < object > Ids )
2011-02-26 11:43:23 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Ids ) ;
2011-02-26 11:43:23 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNodeList MediaById ( List < int > Ids )
2011-03-12 15:19:54 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Ids ) ;
2011-03-12 15:19:54 -13:00
}
2011-06-12 08:23:10 -02:00
[Obsolete("@Model.MediaById is obsolute, use @Library.MediaById")]
2011-06-11 22:15:01 -02:00
public DynamicNodeList MediaById ( params object [ ] Ids )
2011-02-26 11:43:23 -13:00
{
2011-06-12 08:23:10 -02:00
return razorLibrary . Value . MediaById ( Ids ) ;
2011-02-26 11:43:23 -13:00
}
2010-12-08 07:09:45 +00:00
2010-12-25 22:36:12 -11:00
public int template
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return 0 ; return n . template ; }
2010-12-08 07:09:45 +00:00
}
2010-12-25 22:36:12 -11:00
public int SortOrder
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return 0 ; return n . SortOrder ; }
2010-12-25 22:36:12 -11:00
}
public string Name
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . Name ; }
2010-12-25 22:36:12 -11:00
}
2011-02-06 19:52:05 -13:00
public bool Visible
{
2011-03-08 18:09:06 -13:00
get
{
if ( n = = null ) return true ;
IProperty umbracoNaviHide = n . GetProperty ( "umbracoNaviHide" ) ;
if ( umbracoNaviHide ! = null )
{
return umbracoNaviHide . Value ! = "1" ;
}
return true ;
}
2011-02-06 19:52:05 -13:00
}
2010-12-25 22:36:12 -11:00
public string Url
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . Url ; }
2010-12-25 22:36:12 -11:00
}
public string UrlName
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . UrlName ; }
2010-12-25 22:36:12 -11:00
}
public string NodeTypeAlias
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . NodeTypeAlias ; }
2010-12-25 22:36:12 -11:00
}
public string WriterName
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . WriterName ; }
2010-12-25 22:36:12 -11:00
}
public string CreatorName
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . CreatorName ; }
2010-12-25 22:36:12 -11:00
}
public int WriterID
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return 0 ; return n . WriterID ; }
2010-12-25 22:36:12 -11:00
}
public int CreatorID
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return 0 ; return n . CreatorID ; }
2010-12-25 22:36:12 -11:00
}
public string Path
{
get { return n . Path ; }
}
public DateTime CreateDate
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return DateTime . MinValue ; return n . CreateDate ; }
2010-12-25 22:36:12 -11:00
}
2011-06-11 22:15:01 -02:00
public int Id
{
get { if ( n = = null ) return 0 ; return n . Id ; }
}
2010-12-25 22:36:12 -11:00
public DateTime UpdateDate
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return DateTime . MinValue ; return n . UpdateDate ; }
2010-12-25 22:36:12 -11:00
}
public Guid Version
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return Guid . Empty ; return n . Version ; }
2010-12-25 22:36:12 -11:00
}
public string NiceUrl
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . NiceUrl ; }
2010-12-25 22:36:12 -11:00
}
public int Level
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return 0 ; return n . Level ; }
2010-12-25 22:36:12 -11:00
}
public List < IProperty > PropertiesAsList
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . PropertiesAsList ; }
2010-12-25 22:36:12 -11:00
}
2011-06-11 22:15:01 -02:00
public List < DynamicBackingItem > ChildrenAsList
2010-12-25 22:36:12 -11:00
{
2011-01-25 22:24:40 -13:00
get { if ( n = = null ) return null ; return n . ChildrenAsList ; }
2010-12-25 22:36:12 -11:00
}
2010-12-26 17:50:21 -11:00
public IProperty GetProperty ( string alias )
2010-12-25 22:36:12 -11:00
{
2011-01-25 22:24:40 -13:00
if ( n = = null ) return null ;
2010-12-26 17:50:21 -11:00
return n . GetProperty ( alias ) ;
2010-12-25 22:36:12 -11:00
}
2011-03-22 19:01:17 -13:00
public IProperty GetProperty ( string alias , bool recursive )
{
if ( ! recursive ) return GetProperty ( alias ) ;
if ( n = = null ) return null ;
2011-06-11 22:15:01 -02:00
DynamicBackingItem context = this . n ;
2011-03-22 19:01:17 -13:00
IProperty prop = n . GetProperty ( alias ) ;
while ( prop = = null )
{
context = context . Parent ;
if ( context = = null ) break ;
2011-06-12 11:21:44 -02:00
prop = context . GetProperty ( alias ) ;
2011-03-22 19:01:17 -13:00
}
if ( prop ! = null )
{
return prop ;
}
return null ;
}
public string GetPropertyValue ( string alias )
2011-06-12 11:55:38 -02:00
{
return GetPropertyValue ( alias , null ) ;
}
public string GetPropertyValue ( string alias , string fallback )
2011-03-22 19:01:17 -13:00
{
var prop = GetProperty ( alias ) ;
if ( prop ! = null ) return prop . Value ;
2011-06-12 11:55:38 -02:00
return fallback ;
2011-03-22 19:01:17 -13:00
}
public string GetPropertyValue ( string alias , bool recursive )
2011-06-12 11:55:38 -02:00
{
return GetPropertyValue ( alias , recursive , null ) ;
}
public string GetPropertyValue ( string alias , bool recursive , string fallback )
2011-03-22 19:01:17 -13:00
{
var prop = GetProperty ( alias , recursive ) ;
if ( prop ! = null ) return prop . Value ;
2011-06-12 11:55:38 -02:00
return fallback ;
2011-03-22 19:01:17 -13:00
}
2010-12-25 22:36:12 -11:00
public System . Data . DataTable ChildrenAsTable ( )
{
2011-01-25 22:24:40 -13:00
if ( n = = null ) return null ;
2010-12-25 22:36:12 -11:00
return n . ChildrenAsTable ( ) ;
}
public System . Data . DataTable ChildrenAsTable ( string nodeTypeAliasFilter )
{
2011-01-25 22:24:40 -13:00
if ( n = = null ) return null ;
2010-12-25 22:36:12 -11:00
return n . ChildrenAsTable ( nodeTypeAliasFilter ) ;
}
2011-06-12 11:21:44 -02:00
public bool IsNull ( string alias , bool recursive )
2011-06-12 08:23:10 -02:00
{
2011-06-12 11:21:44 -02:00
var prop = GetProperty ( alias ) ;
if ( prop = = null ) return true ;
return ( prop as PropertyResult ) . IsNull ( ) ;
2011-06-12 08:23:10 -02:00
}
2011-06-12 11:21:44 -02:00
public bool IsNull ( string alias )
2011-06-12 08:23:10 -02:00
{
2011-06-12 11:21:44 -02:00
return IsNull ( alias , false ) ;
}
public bool HasValue ( string alias )
{
return HasValue ( alias , false ) ;
}
public bool HasValue ( string alias , bool recursive )
{
var prop = GetProperty ( alias ) ;
if ( prop = = null ) return false ;
return ( prop as PropertyResult ) . HasValue ( ) ;
2011-06-12 08:23:10 -02:00
}
2011-07-11 11:24:00 -12:00
public IHtmlString HasValue ( string alias , string valueIfTrue , string valueIfFalse )
{
return HasValue ( alias , false ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( valueIfFalse ) ;
}
public IHtmlString HasValue ( string alias , bool recursive , string valueIfTrue , string valueIfFalse )
{
return HasValue ( alias , recursive ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( valueIfFalse ) ;
}
public IHtmlString HasValue ( string alias , string valueIfTrue )
{
return HasValue ( alias , false ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( string . Empty ) ;
}
public IHtmlString HasValue ( string alias , bool recursive , string valueIfTrue )
{
return HasValue ( alias , recursive ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( string . Empty ) ;
}
2011-06-12 08:23:10 -02:00
public int Position ( )
{
return this . Index ( ) ;
}
public int Index ( )
{
if ( this . ownerList = = null & & this . Parent ! = null )
{
var list = this . Parent . ChildrenAsList . ConvertAll ( n = > new DynamicNode ( n ) ) ;
this . ownerList = new DynamicNodeList ( list ) ;
}
if ( this . ownerList ! = null )
{
List < DynamicNode > container = this . ownerList . Items . ToList ( ) ;
int currentIndex = container . FindIndex ( n = > n . Id = = this . Id ) ;
if ( currentIndex ! = - 1 )
{
return currentIndex ;
}
else
{
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , this . Id ) ) ;
}
}
else
{
throw new ArgumentNullException ( string . Format ( "Node {0} has been orphaned and doesn't belong to a DynamicNodeList" , this . Id ) ) ;
}
}
public bool IsFirst ( )
{
return IsHelper ( n = > n . Index ( ) = = 0 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsFirst ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) = = 0 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsFirst ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) = = 0 , valueIfTrue , valueIfFalse ) ;
}
public bool IsNotFirst ( )
{
return ! IsHelper ( n = > n . Index ( ) = = 0 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotFirst ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) ! = 0 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotFirst ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) ! = 0 , valueIfTrue , valueIfFalse ) ;
}
public bool IsPosition ( int index )
{
if ( this . ownerList = = null )
{
return false ;
}
return IsHelper ( n = > n . Index ( ) = = index ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsPosition ( int index , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) = = index , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsPosition ( int index , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) = = index , valueIfTrue , valueIfFalse ) ;
}
public bool IsModZero ( int modulus )
{
if ( this . ownerList = = null )
{
return false ;
}
return IsHelper ( n = > n . Index ( ) % modulus = = 0 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsModZero ( int modulus , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) % modulus = = 0 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsModZero ( int modulus , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) % modulus = = 0 , valueIfTrue , valueIfFalse ) ;
}
2011-06-11 22:15:01 -02:00
2011-06-12 08:23:10 -02:00
public bool IsNotModZero ( int modulus )
{
if ( this . ownerList = = null )
{
return false ;
}
return IsHelper ( n = > n . Index ( ) % modulus ! = 0 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotModZero ( int modulus , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) % modulus ! = 0 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotModZero ( int modulus , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) % modulus ! = 0 , valueIfTrue , valueIfFalse ) ;
}
public bool IsNotPosition ( int index )
{
if ( this . ownerList = = null )
{
return false ;
}
return ! IsHelper ( n = > n . Index ( ) = = index ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotPosition ( int index , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) ! = index , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotPosition ( int index , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
return IsHelper ( n = > n . Index ( ) ! = index , valueIfTrue , valueIfFalse ) ;
}
public bool IsLast ( )
{
if ( this . ownerList = = null )
{
return false ;
}
int count = this . ownerList . Items . Count ;
return IsHelper ( n = > n . Index ( ) = = count - 1 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsLast ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
int count = this . ownerList . Items . Count ;
return IsHelper ( n = > n . Index ( ) = = count - 1 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsLast ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
int count = this . ownerList . Items . Count ;
return IsHelper ( n = > n . Index ( ) = = count - 1 , valueIfTrue , valueIfFalse ) ;
}
public bool IsNotLast ( )
{
if ( this . ownerList = = null )
{
return false ;
}
int count = this . ownerList . Items . Count ;
return ! IsHelper ( n = > n . Index ( ) = = count - 1 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotLast ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( string . Empty ) ;
2011-06-12 08:23:10 -02:00
}
int count = this . ownerList . Items . Count ;
return IsHelper ( n = > n . Index ( ) ! = count - 1 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotLast ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
if ( this . ownerList = = null )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
int count = this . ownerList . Items . Count ;
return IsHelper ( n = > n . Index ( ) ! = count - 1 , valueIfTrue , valueIfFalse ) ;
}
public bool IsEven ( )
{
return IsHelper ( n = > n . Index ( ) % 2 = = 0 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsEven ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) % 2 = = 0 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsEven ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) % 2 = = 0 , valueIfTrue , valueIfFalse ) ;
}
public bool IsOdd ( )
{
return IsHelper ( n = > n . Index ( ) % 2 = = 1 ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsOdd ( string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) % 2 = = 1 , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsOdd ( string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Index ( ) % 2 = = 1 , valueIfTrue , valueIfFalse ) ;
}
public bool IsEqual ( DynamicNode other )
{
return IsHelper ( n = > n . Id = = other . Id ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsEqual ( DynamicNode other , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Id = = other . Id , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsEqual ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( n = > n . Id = = other . Id , valueIfTrue , valueIfFalse ) ;
}
2011-06-16 10:55:41 -02:00
public bool IsNotEqual ( DynamicNode other )
{
return IsHelper ( n = > n . Id ! = other . Id ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotEqual ( DynamicNode other , string valueIfTrue )
2011-06-16 10:55:41 -02:00
{
return IsHelper ( n = > n . Id ! = other . Id , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsNotEqual ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-16 10:55:41 -02:00
{
return IsHelper ( n = > n . Id ! = other . Id , valueIfTrue , valueIfFalse ) ;
}
2011-06-12 08:23:10 -02:00
public bool IsDescendant ( DynamicNode other )
{
var ancestors = this . Ancestors ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsDescendant ( DynamicNode other , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
var ancestors = this . Ancestors ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsDescendant ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
var ancestors = this . Ancestors ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null , valueIfTrue , valueIfFalse ) ;
}
public bool IsDescendantOrSelf ( DynamicNode other )
{
var ancestors = this . AncestorsOrSelf ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsDescendantOrSelf ( DynamicNode other , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
var ancestors = this . AncestorsOrSelf ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsDescendantOrSelf ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
var ancestors = this . AncestorsOrSelf ( ) ;
return IsHelper ( n = > ancestors . Items . Find ( ancestor = > ancestor . Id = = other . Id ) ! = null , valueIfTrue , valueIfFalse ) ;
}
public bool IsAncestor ( DynamicNode other )
{
var descendants = this . Descendants ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsAncestor ( DynamicNode other , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
var descendants = this . Descendants ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsAncestor ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
var descendants = this . Descendants ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null , valueIfTrue , valueIfFalse ) ;
}
public bool IsAncestorOrSelf ( DynamicNode other )
{
var descendants = this . DescendantsOrSelf ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsAncestorOrSelf ( DynamicNode other , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
var descendants = this . DescendantsOrSelf ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null , valueIfTrue ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsAncestorOrSelf ( DynamicNode other , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
var descendants = this . DescendantsOrSelf ( ) ;
return IsHelper ( n = > descendants . Items . Find ( descendant = > descendant . Id = = other . Id ) ! = null , valueIfTrue , valueIfFalse ) ;
}
public bool IsHelper ( Func < DynamicNode , bool > test )
{
return test ( this ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsHelper ( Func < DynamicNode , bool > test , string valueIfTrue )
2011-06-12 08:23:10 -02:00
{
return IsHelper ( test , valueIfTrue , string . Empty ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString IsHelper ( Func < DynamicNode , bool > test , string valueIfTrue , string valueIfFalse )
2011-06-12 08:23:10 -02:00
{
2011-07-03 22:41:33 -12:00
return test ( this ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( valueIfFalse ) ;
2011-06-12 08:23:10 -02:00
}
2011-07-03 22:41:33 -12:00
public HtmlString Where ( string predicate , string valueIfTrue )
2011-06-12 13:34:15 -02:00
{
return Where ( predicate , valueIfTrue , string . Empty ) ;
}
2011-07-03 22:41:33 -12:00
public HtmlString Where ( string predicate , string valueIfTrue , string valueIfFalse )
2011-06-13 07:01:04 -02:00
{
if ( Where ( predicate ) )
{
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfTrue ) ;
2011-06-13 07:01:04 -02:00
}
2011-07-03 22:41:33 -12:00
return new HtmlString ( valueIfFalse ) ;
2011-06-13 07:01:04 -02:00
}
public bool Where ( string predicate )
2011-06-12 13:34:15 -02:00
{
//Totally gonna cheat here
var dynamicNodeList = new DynamicNodeList ( ) ;
dynamicNodeList . Add ( this ) ;
var filtered = dynamicNodeList . Where < DynamicNode > ( predicate ) ;
if ( filtered . Count ( ) = = 1 )
{
//this node matches the predicate
2011-06-13 07:01:04 -02:00
return true ;
2011-06-12 13:34:15 -02:00
}
2011-06-13 07:01:04 -02:00
return false ;
2011-06-12 13:34:15 -02:00
}
2010-12-08 07:09:45 +00:00
}
}