2012-09-20 12:42:43 +07:00
using System ;
using System.Collections.Generic ;
2012-12-04 03:26:04 +05:00
using System.Collections.ObjectModel ;
2012-09-20 12:42:43 +07:00
using System.Data ;
using System.Linq ;
2012-10-04 01:31:08 +05:00
using System.Web ;
2012-10-18 08:00:07 +05:00
using Examine.LuceneEngine.SearchCriteria ;
2012-10-04 01:31:08 +05:00
using Umbraco.Core.Dynamics ;
2012-09-20 12:42:43 +07:00
using Umbraco.Core.Models ;
2012-10-04 01:31:08 +05:00
using Umbraco.Web.Models ;
2012-09-20 12:42:43 +07:00
using Umbraco.Web.Routing ;
2012-10-18 08:00:07 +05:00
using umbraco ;
2012-09-20 12:42:43 +07:00
using umbraco.cms.businesslogic ;
using Umbraco.Core ;
2012-10-24 11:02:36 +05:00
using umbraco.cms.businesslogic.template ;
2012-12-04 03:26:04 +05:00
using umbraco.interfaces ;
2012-12-07 20:08:06 +05:00
using ContentType = umbraco . cms . businesslogic . ContentType ;
using Template = umbraco . cms . businesslogic . template . Template ;
2012-09-20 12:42:43 +07:00
namespace Umbraco.Web
{
/// <summary>
2012-10-02 01:35:39 +05:00
/// Extension methods for IPublishedContent
2012-09-20 12:42:43 +07:00
/// </summary>
/// <remarks>
/// These methods exist in the web project as we need access to web based classes like NiceUrl provider
/// which is why they cannot exist in the Core project.
/// </remarks>
2012-10-02 22:51:53 +05:00
public static class PublishedContentExtensions
2012-10-04 01:31:08 +05:00
{
2012-12-04 03:26:04 +05:00
/// <summary>
/// Converts an INode to an IPublishedContent item
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
internal static IPublishedContent ConvertFromNode ( this INode node )
{
var umbHelper = new UmbracoHelper ( UmbracoContext . Current );
return umbHelper . TypedContent ( node . Id );
}
2012-10-24 09:59:23 +05:00
/// <summary>
/// Gets the NiceUrl for the content item
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static string NiceUrl ( this IPublishedContent doc )
{
var umbHelper = new UmbracoHelper ( UmbracoContext . Current );
return umbHelper . NiceUrl ( doc . Id );
}
/// <summary>
/// Gets the NiceUrlWithDomain for the content item
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static string NiceUrlWithDomain ( this IPublishedContent doc )
{
var umbHelper = new UmbracoHelper ( UmbracoContext . Current );
return umbHelper . NiceUrlWithDomain ( doc . Id );
}
2012-10-18 08:00:07 +05:00
/// <summary>
/// Returns the current template Alias
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static string GetTemplateAlias ( this IPublishedContent doc )
{
2012-10-24 11:02:36 +05:00
var template = Template . GetTemplate ( doc . TemplateId );
return template . Alias ;
2012-10-18 08:00:07 +05:00
}
#region Search
public static IEnumerable < IPublishedContent > Search ( this IPublishedContent d , string term , bool useWildCards = true , string searchProvider = null )
{
var searcher = Examine . ExamineManager . Instance . DefaultSearchProvider ;
if (! string . IsNullOrEmpty ( searchProvider ))
searcher = Examine . ExamineManager . Instance . SearchProviderCollection [ searchProvider ];
var t = term . Escape (). Value ;
if ( useWildCards )
t = term . MultipleCharacterWildcard (). Value ;
string luceneQuery = "+__Path:(" + d . Path . Replace ( "-" , "\\-" ) + "*) +" + t ;
var crit = searcher . CreateSearchCriteria (). RawQuery ( luceneQuery );
return d . Search ( crit , searcher );
}
public static IEnumerable < IPublishedContent > SearchDescendants ( this IPublishedContent d , string term , bool useWildCards = true , string searchProvider = null )
{
return d . Search ( term , useWildCards , searchProvider );
}
public static IEnumerable < IPublishedContent > SearchChildren ( this IPublishedContent d , string term , bool useWildCards = true , string searchProvider = null )
{
var searcher = Examine . ExamineManager . Instance . DefaultSearchProvider ;
if (! string . IsNullOrEmpty ( searchProvider ))
searcher = Examine . ExamineManager . Instance . SearchProviderCollection [ searchProvider ];
var t = term . Escape (). Value ;
if ( useWildCards )
t = term . MultipleCharacterWildcard (). Value ;
string luceneQuery = "+parentID:" + d . Id . ToString () + " +" + t ;
var crit = searcher . CreateSearchCriteria (). RawQuery ( luceneQuery );
return d . Search ( crit , searcher );
}
public static IEnumerable < IPublishedContent > Search ( this IPublishedContent d , Examine . SearchCriteria . ISearchCriteria criteria , Examine . Providers . BaseSearchProvider searchProvider = null )
{
var s = Examine . ExamineManager . Instance . DefaultSearchProvider ;
if ( searchProvider != null )
s = searchProvider ;
var results = s . Search ( criteria );
return results . ConvertSearchResultToPublishedContent ( PublishedContentStoreResolver . Current . PublishedContentStore );
}
#endregion
2012-10-04 01:31:08 +05:00
2012-10-04 03:26:56 +05:00
#region List Extensions
public static IQueryable < IPublishedContent > OrderBy ( this IEnumerable < IPublishedContent > list , string predicate )
{
var dList = new DynamicPublishedContentList ( list );
return dList . OrderBy < DynamicPublishedContent >( predicate );
}
public static IQueryable < IPublishedContent > Where ( this IEnumerable < IPublishedContent > list , string predicate )
{
var dList = new DynamicPublishedContentList ( list );
return dList . Where < DynamicPublishedContent >( predicate );
}
public static IEnumerable < IGrouping < object , IPublishedContent >> GroupBy ( this IEnumerable < IPublishedContent > list , string predicate )
{
var dList = new DynamicPublishedContentList ( list );
return dList . GroupBy ( predicate );
}
public static IQueryable Select ( this IEnumerable < IPublishedContent > list , string predicate , params object [] values )
{
var dList = new DynamicPublishedContentList ( list );
return dList . Select ( predicate );
}
#endregion
public static dynamic AsDynamic ( this IPublishedContent doc )
{
if ( doc == null ) throw new ArgumentNullException ( "doc" );
var dd = new DynamicPublishedContent ( doc );
return dd . AsDynamic ();
}
2012-10-04 01:31:08 +05:00
/// <summary>
/// Converts a IPublishedContent to a DynamicPublishedContent and tests for null
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
internal static DynamicPublishedContent AsDynamicPublishedContent ( this IPublishedContent content )
{
if ( content == null )
return null ;
return new DynamicPublishedContent ( content );
}
2012-10-04 03:26:56 +05:00
#region Where
public static HtmlString Where ( this IPublishedContent doc , string predicate , string valueIfTrue )
2012-10-04 01:31:08 +05:00
{
2012-10-04 03:26:56 +05:00
if ( doc == null ) throw new ArgumentNullException ( "doc" );
return doc . Where ( predicate , valueIfTrue , string . Empty );
2012-10-04 01:31:08 +05:00
}
2012-10-04 03:26:56 +05:00
public static HtmlString Where ( this IPublishedContent doc , string predicate , string valueIfTrue , string valueIfFalse )
2012-10-04 01:31:08 +05:00
{
2012-10-04 03:26:56 +05:00
if ( doc == null ) throw new ArgumentNullException ( "doc" );
if ( doc . Where ( predicate ))
2012-10-04 01:31:08 +05:00
{
2012-10-04 03:26:56 +05:00
return new HtmlString ( valueIfTrue );
2012-10-04 01:31:08 +05:00
}
2012-10-04 03:26:56 +05:00
return new HtmlString ( valueIfFalse );
2012-10-04 01:31:08 +05:00
}
2012-10-04 03:26:56 +05:00
public static bool Where ( this IPublishedContent doc , string predicate )
{
if ( doc == null ) throw new ArgumentNullException ( "doc" );
//Totally gonna cheat here
var dynamicDocumentList = new DynamicPublishedContentList ();
dynamicDocumentList . Add ( doc . AsDynamicPublishedContent ());
var filtered = dynamicDocumentList . Where < DynamicPublishedContent >( predicate );
if ( Queryable . Count ( filtered ) == 1 )
{
//this node matches the predicate
return true ;
}
return false ;
}
#endregion
2012-10-04 01:31:08 +05:00
#region Position / Index
public static int Position ( this IPublishedContent content )
{
return content . Index ();
}
public static int Index ( this IPublishedContent content )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
int currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
return currentIndex ;
}
else
{
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicDocumentList but could not retrieve the index for it's position in the list" , content . Id ));
}
}
#endregion
#region Is Helpers
2012-10-06 23:41:42 +05:00
public static bool IsDocumentType ( this IPublishedContent content , string docTypeAlias )
{
return content . DocumentTypeAlias == docTypeAlias ;
}
2012-10-04 01:31:08 +05:00
public static bool IsNull ( this IPublishedContent content , string alias , bool recursive )
{
var prop = content . GetProperty ( alias , recursive );
if ( prop == null ) return true ;
return (( PropertyResult ) prop ). HasValue ();
}
public static bool IsNull ( this IPublishedContent content , string alias )
{
return content . IsNull ( alias , false );
}
public static bool IsFirst ( this IPublishedContent content )
{
return content . IsHelper ( n => n . Index () == 0 );
}
public static HtmlString IsFirst ( this IPublishedContent content , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () == 0 , valueIfTrue );
}
public static HtmlString IsFirst ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () == 0 , valueIfTrue , valueIfFalse );
}
public static bool IsNotFirst ( this IPublishedContent content )
{
return ! content . IsHelper ( n => n . Index () == 0 );
}
public static HtmlString IsNotFirst ( this IPublishedContent content , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () != 0 , valueIfTrue );
}
public static HtmlString IsNotFirst ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () != 0 , valueIfTrue , valueIfFalse );
}
public static bool IsPosition ( this IPublishedContent content , int index )
{
return content . IsHelper ( n => n . Index () == index );
}
public static HtmlString IsPosition ( this IPublishedContent content , int index , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () == index , valueIfTrue );
}
public static HtmlString IsPosition ( this IPublishedContent content , int index , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () == index , valueIfTrue , valueIfFalse );
}
public static bool IsModZero ( this IPublishedContent content , int modulus )
{
return content . IsHelper ( n => n . Index () % modulus == 0 );
}
public static HtmlString IsModZero ( this IPublishedContent content , int modulus , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () % modulus == 0 , valueIfTrue );
}
public static HtmlString IsModZero ( this IPublishedContent content , int modulus , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () % modulus == 0 , valueIfTrue , valueIfFalse );
}
public static bool IsNotModZero ( this IPublishedContent content , int modulus )
{
return content . IsHelper ( n => n . Index () % modulus != 0 );
}
public static HtmlString IsNotModZero ( this IPublishedContent content , int modulus , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () % modulus != 0 , valueIfTrue );
}
public static HtmlString IsNotModZero ( this IPublishedContent content , int modulus , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () % modulus != 0 , valueIfTrue , valueIfFalse );
}
public static bool IsNotPosition ( this IPublishedContent content , int index )
{
return ! content . IsHelper ( n => n . Index () == index );
}
public static HtmlString IsNotPosition ( this IPublishedContent content , int index , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () != index , valueIfTrue );
}
public static HtmlString IsNotPosition ( this IPublishedContent content , int index , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () != index , valueIfTrue , valueIfFalse );
}
public static bool IsLast ( this IPublishedContent content )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return content . IsHelper ( n => n . Index () == count - 1 );
}
public static HtmlString IsLast ( this IPublishedContent content , string valueIfTrue )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return content . IsHelper ( n => n . Index () == count - 1 , valueIfTrue );
}
public static HtmlString IsLast ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return content . IsHelper ( n => n . Index () == count - 1 , valueIfTrue , valueIfFalse );
}
public static bool IsNotLast ( this IPublishedContent content )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return ! content . IsHelper ( n => n . Index () == count - 1 );
}
public static HtmlString IsNotLast ( this IPublishedContent content , string valueIfTrue )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return content . IsHelper ( n => n . Index () != count - 1 , valueIfTrue );
}
public static HtmlString IsNotLast ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var count = ownersList . Count ();
return content . IsHelper ( n => n . Index () != count - 1 , valueIfTrue , valueIfFalse );
}
public static bool IsEven ( this IPublishedContent content )
{
return content . IsHelper ( n => n . Index () % 2 == 0 );
}
public static HtmlString IsEven ( this IPublishedContent content , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () % 2 == 0 , valueIfTrue );
}
public static HtmlString IsEven ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () % 2 == 0 , valueIfTrue , valueIfFalse );
}
public static bool IsOdd ( this IPublishedContent content )
{
return content . IsHelper ( n => n . Index () % 2 == 1 );
}
public static HtmlString IsOdd ( this IPublishedContent content , string valueIfTrue )
{
return content . IsHelper ( n => n . Index () % 2 == 1 , valueIfTrue );
}
public static HtmlString IsOdd ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Index () % 2 == 1 , valueIfTrue , valueIfFalse );
}
public static bool IsEqual ( this IPublishedContent content , IPublishedContent other )
{
return content . IsHelper ( n => n . Id == other . Id );
}
public static HtmlString IsEqual ( this IPublishedContent content , IPublishedContent other , string valueIfTrue )
{
return content . IsHelper ( n => n . Id == other . Id , valueIfTrue );
}
public static HtmlString IsEqual ( this IPublishedContent content , IPublishedContent other , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Id == other . Id , valueIfTrue , valueIfFalse );
}
public static bool IsNotEqual ( this IPublishedContent content , IPublishedContent other )
{
return content . IsHelper ( n => n . Id != other . Id );
}
public static HtmlString IsNotEqual ( this IPublishedContent content , IPublishedContent other , string valueIfTrue )
{
return content . IsHelper ( n => n . Id != other . Id , valueIfTrue );
}
public static HtmlString IsNotEqual ( this IPublishedContent content , IPublishedContent other , string valueIfTrue , string valueIfFalse )
{
return content . IsHelper ( n => n . Id != other . Id , valueIfTrue , valueIfFalse );
}
public static bool IsDescendant ( this IPublishedContent content , IPublishedContent other )
{
var ancestors = content . Ancestors ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null );
}
public static HtmlString IsDescendant ( this IPublishedContent content , IPublishedContent other , string valueIfTrue )
{
var ancestors = content . Ancestors ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null , valueIfTrue );
}
public static HtmlString IsDescendant ( this IPublishedContent content , IPublishedContent other , string valueIfTrue , string valueIfFalse )
{
var ancestors = content . Ancestors ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null , valueIfTrue , valueIfFalse );
}
public static bool IsDescendantOrSelf ( this IPublishedContent content , IPublishedContent other )
{
var ancestors = content . AncestorsOrSelf ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsDescendantOrSelf ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue )
2012-10-04 01:31:08 +05:00
{
var ancestors = content . AncestorsOrSelf ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null , valueIfTrue );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsDescendantOrSelf ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue , string valueIfFalse )
2012-10-04 01:31:08 +05:00
{
var ancestors = content . AncestorsOrSelf ();
return content . IsHelper ( n => ancestors . FirstOrDefault ( ancestor => ancestor . Id == other . Id ) != null , valueIfTrue , valueIfFalse );
}
2012-10-04 03:26:56 +05:00
public static bool IsAncestor ( this IPublishedContent content , DynamicPublishedContent other )
2012-10-04 01:31:08 +05:00
{
var descendants = content . Descendants ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsAncestor ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue )
2012-10-04 01:31:08 +05:00
{
var descendants = content . Descendants ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null , valueIfTrue );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsAncestor ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue , string valueIfFalse )
2012-10-04 01:31:08 +05:00
{
var descendants = content . Descendants ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null , valueIfTrue , valueIfFalse );
}
2012-10-04 03:26:56 +05:00
public static bool IsAncestorOrSelf ( this IPublishedContent content , DynamicPublishedContent other )
2012-10-04 01:31:08 +05:00
{
var descendants = content . DescendantsOrSelf ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsAncestorOrSelf ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue )
2012-10-04 01:31:08 +05:00
{
var descendants = content . DescendantsOrSelf ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null , valueIfTrue );
}
2012-10-04 03:26:56 +05:00
public static HtmlString IsAncestorOrSelf ( this IPublishedContent content , DynamicPublishedContent other , string valueIfTrue , string valueIfFalse )
2012-10-04 01:31:08 +05:00
{
var descendants = content . DescendantsOrSelf ();
return content . IsHelper ( n => descendants . FirstOrDefault ( descendant => descendant . Id == other . Id ) != null , valueIfTrue , valueIfFalse );
}
private static bool IsHelper ( this IPublishedContent content , Func < IPublishedContent , bool > test )
{
return test ( content );
}
private static HtmlString IsHelper ( this IPublishedContent content , Func < IPublishedContent , bool > test , string valueIfTrue )
{
return content . IsHelper ( test , valueIfTrue , string . Empty );
}
private static HtmlString IsHelper ( this IPublishedContent content , Func < IPublishedContent , bool > test , string valueIfTrue , string valueIfFalse )
{
return test ( content ) ? new HtmlString ( valueIfTrue ) : new HtmlString ( valueIfFalse );
}
#endregion
#region Ancestors
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , int level )
{
return content . Ancestors ( n => n . Level <= level );
}
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , string nodeTypeAlias )
{
return content . Ancestors ( n => n . DocumentTypeAlias == nodeTypeAlias );
}
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content )
{
return content . Ancestors ( n => true );
}
2012-10-08 23:32:43 +05:00
internal static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2012-10-04 01:31:08 +05:00
{
var ancestorList = new List < IPublishedContent >();
var node = content ;
while ( node != null )
{
if ( node . Level == 1 ) break ;
var parent = node . Parent ;
if ( parent == null )
{
break ;
}
if ( content != parent )
{
node = parent ;
if ( func ( node ))
{
ancestorList . Add ( node );
}
}
else
{
break ;
}
}
ancestorList . Reverse ();
return ancestorList ;
}
public static IPublishedContent AncestorOrSelf ( this IPublishedContent content )
{
//TODO: Why is this query like this??
return content . AncestorOrSelf ( node => node . Level == 1 );
}
public static IPublishedContent AncestorOrSelf ( this IPublishedContent content , int level )
{
return content . AncestorOrSelf ( node => node . Level == level );
}
public static IPublishedContent AncestorOrSelf ( this IPublishedContent content , string nodeTypeAlias )
{
return content . AncestorOrSelf ( node => node . DocumentTypeAlias == nodeTypeAlias );
}
2012-10-08 23:32:43 +05:00
internal static IPublishedContent AncestorOrSelf ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2012-10-04 01:31:08 +05:00
{
var node = content ;
while ( node != null )
{
if ( func ( node )) return node ;
var parent = node . Parent ;
if ( parent == null )
{
return null ;
}
if ( content != parent )
{
node = parent ;
}
else
{
return node ;
}
}
return null ;
}
2012-10-08 21:55:03 +05:00
internal static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2012-10-04 01:31:08 +05:00
{
var ancestorList = new List < IPublishedContent >();
var node = content ;
ancestorList . Add ( node );
while ( node != null )
{
if ( node . Level == 1 ) break ;
var parent = node . Parent ;
if ( parent == null )
{
break ;
}
if ( content != parent )
{
node = parent ;
if ( func ( node ))
{
ancestorList . Add ( node );
}
}
else
{
break ;
}
}
ancestorList . Reverse ();
return ancestorList ;
}
public static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content )
{
return content . AncestorsOrSelf ( n => true );
}
public static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , string nodeTypeAlias )
{
return content . AncestorsOrSelf ( n => n . DocumentTypeAlias == nodeTypeAlias );
}
2012-10-08 23:32:43 +05:00
internal static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , int level )
2012-10-04 01:31:08 +05:00
{
return content . AncestorsOrSelf ( n => n . Level <= level );
}
#endregion
#region Descendants
public static IEnumerable < IPublishedContent > Descendants ( this IPublishedContent content , string nodeTypeAlias )
{
return content . Descendants ( p => p . DocumentTypeAlias == nodeTypeAlias );
}
public static IEnumerable < IPublishedContent > Descendants ( this IPublishedContent content , int level )
{
return content . Descendants ( p => p . Level >= level );
}
public static IEnumerable < IPublishedContent > Descendants ( this IPublishedContent content )
{
return content . Descendants ( n => true );
}
2012-10-08 21:55:03 +05:00
private static IEnumerable < IPublishedContent > Descendants ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2012-10-04 01:31:08 +05:00
{
return content . Children . Map ( func , ( IPublishedContent n ) => n . Children );
}
public static IEnumerable < IPublishedContent > DescendantsOrSelf ( this IPublishedContent content , int level )
{
return content . DescendantsOrSelf ( p => p . Level >= level );
}
public static IEnumerable < IPublishedContent > DescendantsOrSelf ( this IPublishedContent content , string nodeTypeAlias )
{
return content . DescendantsOrSelf ( p => p . DocumentTypeAlias == nodeTypeAlias );
}
public static IEnumerable < IPublishedContent > DescendantsOrSelf ( this IPublishedContent content )
{
return content . DescendantsOrSelf ( p => true );
}
2012-10-08 23:32:43 +05:00
internal static IEnumerable < IPublishedContent > DescendantsOrSelf ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2012-10-04 01:31:08 +05:00
{
if ( content != null )
{
var thisNode = new List < IPublishedContent >();
if ( func ( content ))
{
thisNode . Add ( content );
}
var flattenedNodes = content . Children . Map ( func , ( IPublishedContent n ) => n . Children );
2012-10-04 03:26:56 +05:00
return thisNode . Concat ( flattenedNodes ). ToList (). ConvertAll ( dynamicBackingItem => new DynamicPublishedContent ( dynamicBackingItem ));
2012-10-04 01:31:08 +05:00
}
return Enumerable . Empty < IPublishedContent >();
}
#endregion
#region Traversal
public static IPublishedContent Up ( this IPublishedContent content )
{
return content . Up ( 0 );
}
public static IPublishedContent Up ( this IPublishedContent content , int number )
{
if ( number == 0 )
{
return content . Parent ;
}
while (( content = content . Parent ) != null && -- number >= 0 ) ;
return content ;
}
public static IPublishedContent Up ( this IPublishedContent content , string nodeTypeAlias )
{
if ( string . IsNullOrEmpty ( nodeTypeAlias ))
{
return content . Parent ;
}
while (( content = content . Parent ) != null && content . DocumentTypeAlias != nodeTypeAlias ) ;
return content ;
}
public static IPublishedContent Down ( this IPublishedContent content )
{
return content . Down ( 0 );
}
public static IPublishedContent Down ( this IPublishedContent content , int number )
{
var children = content . Children ;
if ( number == 0 )
{
return children . First ();
}
var working = content ;
while ( number -- >= 0 )
{
working = children . First ();
children = new DynamicPublishedContentList ( working . Children );
}
return working ;
}
public static IPublishedContent Down ( this IPublishedContent content , string nodeTypeAlias )
{
if ( string . IsNullOrEmpty ( nodeTypeAlias ))
{
var children = content . Children ;
return children . First ();
}
return content . Descendants ( nodeTypeAlias ). FirstOrDefault ();
}
public static IPublishedContent Next ( this IPublishedContent content )
{
return content . Next ( 0 );
}
public static IPublishedContent Next ( this IPublishedContent content , int number )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
var currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
return container . ElementAtOrDefault ( currentIndex + ( number + 1 ));
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
public static IPublishedContent Next ( this IPublishedContent content , string nodeTypeAlias )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
var currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
var newIndex = container . FindIndex ( currentIndex , n => n . DocumentTypeAlias == nodeTypeAlias );
return newIndex != - 1
? container . ElementAt ( newIndex )
: null ;
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
public static IPublishedContent Previous ( this IPublishedContent content )
{
return content . Previous ( 0 );
}
public static IPublishedContent Previous ( this IPublishedContent content , int number )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
var currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
return container . ElementAtOrDefault ( currentIndex + ( number - 1 ));
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
public static IPublishedContent Previous ( this IPublishedContent content , string nodeTypeAlias )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
int currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
var previousNodes = container . Take ( currentIndex ). ToList ();
int newIndex = previousNodes . FindIndex ( n => n . DocumentTypeAlias == nodeTypeAlias );
if ( newIndex != - 1 )
{
return container . ElementAt ( newIndex );
}
return null ;
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
public static IPublishedContent Sibling ( this IPublishedContent content , int number )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
var currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
return container . ElementAtOrDefault ( currentIndex + number );
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
public static IPublishedContent Sibling ( this IPublishedContent content , string nodeTypeAlias )
{
//get the root docs if parent is null
var ownersList = content . Parent == null
? PublishedContentStoreResolver . Current . PublishedContentStore . GetRootDocuments ( UmbracoContext . Current )
: content . Parent . Children ;
var container = ownersList . ToList ();
var currentIndex = container . FindIndex ( n => n . Id == content . Id );
if ( currentIndex != - 1 )
{
var workingIndex = currentIndex + 1 ;
while ( workingIndex != currentIndex )
{
var working = container . ElementAtOrDefault ( workingIndex );
if ( working != null && working . DocumentTypeAlias == nodeTypeAlias )
{
return working ;
}
workingIndex ++;
if ( workingIndex > container . Count )
{
workingIndex = 0 ;
}
}
return null ;
}
throw new IndexOutOfRangeException ( string . Format ( "Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list" , content . Id ));
}
#endregion
2012-09-20 12:42:43 +07:00
2012-10-08 21:55:03 +05:00
/// <summary>
/// Method to return the Children of the content item
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
/// <remarks>
/// This method exists for consistency, it is the same as calling content.Children as a property.
/// </remarks>
public static IEnumerable < IPublishedContent > Children ( this IPublishedContent p )
{
return p . Children ;
}
2012-09-20 12:42:43 +07:00
/// <summary>
2012-10-02 01:35:39 +05:00
/// Returns a DataTable object for the IPublishedContent
2012-09-20 12:42:43 +07:00
/// </summary>
/// <param name="d"></param>
/// <param name="nodeTypeAliasFilter"></param>
/// <returns></returns>
2012-10-02 01:35:39 +05:00
public static DataTable ChildrenAsTable ( this IPublishedContent d , string nodeTypeAliasFilter = "" )
2012-09-20 12:42:43 +07:00
{
return GenerateDataTable ( d , nodeTypeAliasFilter );
}
/// <summary>
2012-10-02 01:35:39 +05:00
/// Generates the DataTable for the IPublishedContent
2012-09-20 12:42:43 +07:00
/// </summary>
/// <param name="node"></param>
/// <param name="nodeTypeAliasFilter"> </param>
/// <returns></returns>
2012-10-02 01:35:39 +05:00
private static DataTable GenerateDataTable ( IPublishedContent node , string nodeTypeAliasFilter = "" )
2012-09-20 12:42:43 +07:00
{
var firstNode = nodeTypeAliasFilter . IsNullOrWhiteSpace ()
? node . Children . Any ()
? node . Children . ElementAt ( 0 )
: null
: node . Children . FirstOrDefault ( x => x . DocumentTypeAlias == nodeTypeAliasFilter );
if ( firstNode == null )
return new DataTable (); //no children found
var urlProvider = UmbracoContext . Current . RoutingContext . NiceUrlProvider ;
//use new utility class to create table so that we don't have to maintain code in many places, just one
var dt = Umbraco . Core . DataTableExtensions . GenerateDataTable (
//pass in the alias of the first child node since this is the node type we're rendering headers for
firstNode . DocumentTypeAlias ,
//pass in the callback to extract the Dictionary<string, string> of all defined aliases to their names
alias => GetPropertyAliasesAndNames ( alias ),
//pass in a callback to populate the datatable, yup its a bit ugly but it's already legacy and we just want to maintain code in one place.
() =>
{
//create all row data
var tableData = Umbraco . Core . DataTableExtensions . CreateTableData ();
//loop through each child and create row data for it
foreach ( var n in node . Children )
{
if (! nodeTypeAliasFilter . IsNullOrWhiteSpace ())
{
if ( n . DocumentTypeAlias != nodeTypeAliasFilter )
continue ; //skip this one, it doesn't match the filter
}
var standardVals = new Dictionary < string , object >()
{
{ "Id" , n . Id },
{ "NodeName" , n . Name },
{ "NodeTypeAlias" , n . DocumentTypeAlias },
{ "CreateDate" , n . CreateDate },
{ "UpdateDate" , n . UpdateDate },
{ "CreatorName" , n . CreatorName },
{ "WriterName" , n . WriterName },
{ "Url" , urlProvider . GetNiceUrl ( n . Id )}
};
var userVals = new Dictionary < string , object >();
2012-10-04 03:26:56 +05:00
foreach ( var p in from IPublishedContentProperty p in n . Properties where p . Value != null select p )
2012-09-20 12:42:43 +07:00
{
userVals [ p . Alias ] = p . Value ;
}
//add the row data
Umbraco . Core . DataTableExtensions . AddRowData ( tableData , standardVals , userVals );
}
return tableData ;
}
);
return dt ;
}
private static Func < string , Dictionary < string , string >> _getPropertyAliasesAndNames ;
/// <summary>
/// This is used only for unit tests to set the delegate to look up aliases/names dictionary of a content type
/// </summary>
internal static Func < string , Dictionary < string , string >> GetPropertyAliasesAndNames
{
get
{
return _getPropertyAliasesAndNames ?? ( _getPropertyAliasesAndNames = alias =>
{
var userFields = ContentType . GetAliasesAndNames ( alias );
//ensure the standard fields are there
var allFields = new Dictionary < string , string >()
{
{ "Id" , "Id" },
{ "NodeName" , "NodeName" },
{ "NodeTypeAlias" , "NodeTypeAlias" },
{ "CreateDate" , "CreateDate" },
{ "UpdateDate" , "UpdateDate" },
{ "CreatorName" , "CreatorName" },
{ "WriterName" , "WriterName" },
{ "Url" , "Url" }
};
foreach ( var f in userFields . Where ( f => ! allFields . ContainsKey ( f . Key )))
{
allFields . Add ( f . Key , f . Value );
}
return allFields ;
});
}
set { _getPropertyAliasesAndNames = value ; }
}
}
}