2012-09-20 12:42:43 +07:00
using System ;
2013-03-02 01:02:38 +06:00
using System.Collections ;
2012-09-20 12:42:43 +07:00
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 ;
2013-02-05 06:31:13 -01:00
using Umbraco.Web.PublishedCache ;
2012-09-20 12:42:43 +07:00
using Umbraco.Web.Routing ;
2012-12-09 03:22:11 +05:00
using Umbraco.Web.Templates ;
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>
2012-12-09 03:53:16 +05:00
[Obsolete("NiceUrl() is obsolete, use the Url() method instead")]
2012-10-24 09:59:23 +05:00
public static string NiceUrl ( this IPublishedContent doc )
2012-12-09 03:53:16 +05:00
{
return doc . Url ( ) ;
}
/// <summary>
/// Gets the Url for the content item
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static string Url ( this IPublishedContent doc )
2012-10-24 09:59:23 +05:00
{
2012-12-09 03:51:02 +05:00
switch ( doc . ItemType )
{
case PublishedItemType . Content :
var umbHelper = new UmbracoHelper ( UmbracoContext . Current ) ;
return umbHelper . NiceUrl ( doc . Id ) ;
case PublishedItemType . Media :
2013-03-18 17:55:02 +00:00
var prop = doc . GetProperty ( Constants . Conventions . Media . File ) ;
2012-12-09 03:51:02 +05:00
if ( prop = = null )
throw new NotSupportedException ( "Cannot retreive a Url for a media item if there is no 'umbracoFile' property defined" ) ;
return prop . Value . ToString ( ) ;
default :
throw new ArgumentOutOfRangeException ( ) ;
}
2012-10-24 09:59:23 +05:00
}
/// <summary>
/// Gets the NiceUrlWithDomain for the content item
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
2012-12-09 03:53:16 +05:00
[Obsolete("NiceUrlWithDomain() is obsolete, use the UrlWithDomain() method instead")]
2012-10-24 09:59:23 +05:00
public static string NiceUrlWithDomain ( this IPublishedContent doc )
2012-12-09 03:53:16 +05:00
{
return doc . UrlWithDomain ( ) ;
}
/// <summary>
/// Gets the UrlWithDomain for the content item
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static string UrlWithDomain ( this IPublishedContent doc )
2012-10-24 09:59:23 +05:00
{
2012-12-09 03:51:02 +05:00
switch ( doc . ItemType )
{
case PublishedItemType . Content :
var umbHelper = new UmbracoHelper ( UmbracoContext . Current ) ;
return umbHelper . NiceUrlWithDomain ( doc . Id ) ;
case PublishedItemType . Media :
throw new NotSupportedException ( "NiceUrlWithDomain is not supported for media types" ) ;
default :
throw new ArgumentOutOfRangeException ( ) ;
}
2012-10-24 09:59:23 +05:00
}
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 ) ;
2013-08-23 14:08:13 +02:00
return template ! = null ? template . Alias : string . Empty ;
2012-10-18 08:00:07 +05:00
}
2012-12-09 03:22:11 +05:00
#region GetPropertyValue
/// <summary>
/// if the val is a string, ensures all internal local links are parsed
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
internal static object GetValueWithParsedLinks ( object val )
{
//if it is a string send it through the url parser
var text = val as string ;
if ( text ! = null )
{
return TemplateUtilities . ResolveUrlsFromTextString (
TemplateUtilities . ParseInternalLinks ( text ) ) ;
}
//its not a string
return val ;
}
public static object GetPropertyValue ( this IPublishedContent doc , string alias )
{
return doc . GetPropertyValue ( alias , false ) ;
}
public static object GetPropertyValue ( this IPublishedContent doc , string alias , string fallback )
{
var prop = doc . GetPropertyValue ( alias ) ;
return ( prop ! = null & & ! Convert . ToString ( prop ) . IsNullOrWhiteSpace ( ) ) ? prop : fallback ;
}
public static object GetPropertyValue ( this IPublishedContent doc , string alias , bool recursive )
{
var p = doc . GetProperty ( alias , recursive ) ;
if ( p = = null ) return null ;
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
2013-08-29 11:59:07 +10:00
var dataType = PublishedContentHelper . GetDataType (
ApplicationContext . Current , doc . DocumentTypeAlias , alias ,
doc . ItemType ) ;
2012-12-09 03:22:11 +05:00
//convert the string value to a known type
var converted = PublishedContentHelper . ConvertPropertyValue ( p . Value , dataType , doc . DocumentTypeAlias , alias ) ;
return converted . Success
2012-12-09 03:51:02 +05:00
? GetValueWithParsedLinks ( converted . Result )
: GetValueWithParsedLinks ( p . Value ) ;
2012-12-09 03:22:11 +05:00
}
public static object GetPropertyValue ( this IPublishedContent doc , string alias , bool recursive , string fallback )
{
var prop = doc . GetPropertyValue ( alias , recursive ) ;
return ( prop ! = null & & ! Convert . ToString ( prop ) . IsNullOrWhiteSpace ( ) ) ? prop : fallback ;
}
/// <summary>
/// Returns the property as the specified type, if the property is not found or does not convert
/// then the default value of type T is returned.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="doc"></param>
/// <param name="alias"></param>
/// <returns></returns>
public static T GetPropertyValue < T > ( this IPublishedContent doc , string alias )
{
return doc . GetPropertyValue < T > ( alias , default ( T ) ) ;
}
public static T GetPropertyValue < T > ( this IPublishedContent prop , string alias , bool recursive , T ifCannotConvert )
{
var p = prop . GetProperty ( alias , recursive ) ;
if ( p = = null )
return ifCannotConvert ;
//before we try to convert it manually, lets see if the PropertyEditorValueConverter does this for us
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
2013-08-29 12:01:30 +10:00
var dataType = PublishedContentHelper . GetDataType ( ApplicationContext . Current , prop . DocumentTypeAlias , alias , prop . ItemType ) ;
2012-12-09 03:22:11 +05:00
//convert the value to a known type
var converted = PublishedContentHelper . ConvertPropertyValue ( p . Value , dataType , prop . DocumentTypeAlias , alias ) ;
object parsedLinksVal ;
if ( converted . Success )
{
parsedLinksVal = GetValueWithParsedLinks ( converted . Result ) ;
//if its successful, check if its the correct type and return it
if ( parsedLinksVal is T )
{
return ( T ) parsedLinksVal ;
}
//if that's not correct, try converting the converted type
var reConverted = converted . Result . TryConvertTo < T > ( ) ;
if ( reConverted . Success )
{
return reConverted . Result ;
}
}
//first, parse links if possible
parsedLinksVal = GetValueWithParsedLinks ( p . Value ) ;
//last, if all the above has failed, we'll just try converting the raw value straight to 'T'
var manualConverted = parsedLinksVal . TryConvertTo < T > ( ) ;
if ( manualConverted . Success )
return manualConverted . Result ;
return ifCannotConvert ;
}
public static T GetPropertyValue < T > ( this IPublishedContent prop , string alias , T ifCannotConvert )
{
return prop . GetPropertyValue < T > ( alias , false , ifCannotConvert ) ;
}
#endregion
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 ) ;
2013-03-19 17:51:55 -01:00
return results . ConvertSearchResultToPublishedContent ( UmbracoContext . Current . ContentCache ) ;
2012-12-09 03:51:02 +05:00
}
2012-10-18 08:00:07 +05:00
#endregion
2012-10-04 01:31:08 +05:00
2013-03-02 01:02:38 +06:00
#region Linq Wrapping Extensions
//NOTE: These are all purely required to fix this issue: http://issues.umbraco.org/issue/U4-1797 which requires that any
// content item knows about it's containing collection.
public static IEnumerable < IPublishedContent > Where ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , bool > predicate )
{
var internalResult = Enumerable . Where ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Where ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , int , bool > predicate )
{
var internalResult = Enumerable . Where ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Take ( this IEnumerable < IPublishedContent > source , int count )
{
var internalResult = Enumerable . Take ( source , count ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > TakeWhile ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , bool > predicate )
{
var internalResult = Enumerable . TakeWhile ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > TakeWhile ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , int , bool > predicate )
{
var internalResult = Enumerable . TakeWhile ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Skip ( this IEnumerable < IPublishedContent > source , int count )
{
var internalResult = Enumerable . Skip ( source , count ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > SkipWhile ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , bool > predicate )
{
var internalResult = Enumerable . SkipWhile ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > SkipWhile ( this IEnumerable < IPublishedContent > source , Func < IPublishedContent , int , bool > predicate )
{
var internalResult = Enumerable . SkipWhile ( source , predicate ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Concat ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second )
{
var internalResult = Enumerable . Concat ( first , second ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Distinct ( this IEnumerable < IPublishedContent > source )
{
var internalResult = Enumerable . Distinct ( source ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Distinct ( this IEnumerable < IPublishedContent > source , IEqualityComparer < IPublishedContent > comparer )
{
var internalResult = Enumerable . Distinct ( source , comparer ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Union ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second )
{
var internalResult = Enumerable . Union ( first , second ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Union ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second , IEqualityComparer < IPublishedContent > comparer )
{
var internalResult = Enumerable . Union ( first , second , comparer ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Intersect ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second )
{
var internalResult = Enumerable . Intersect ( first , second ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Intersect ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second , IEqualityComparer < IPublishedContent > comparer )
{
var internalResult = Enumerable . Intersect ( first , second , comparer ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Except ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second )
{
var internalResult = Enumerable . Except ( first , second ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Except ( this IEnumerable < IPublishedContent > first , IEnumerable < IPublishedContent > second , IEqualityComparer < IPublishedContent > comparer )
{
var internalResult = Enumerable . Except ( first , second , comparer ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > Reverse ( this IEnumerable < IPublishedContent > source )
{
var internalResult = Enumerable . Reverse ( source ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > DefaultIfEmpty ( this IEnumerable < IPublishedContent > source )
{
var internalResult = Enumerable . DefaultIfEmpty ( source ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
public static IEnumerable < IPublishedContent > DefaultIfEmpty ( this IEnumerable < IPublishedContent > source , IPublishedContent defaultValue )
{
var internalResult = Enumerable . DefaultIfEmpty ( source , defaultValue ) ;
return new DynamicPublishedContentList ( internalResult ) ;
}
#endregion
#region Dynamic Linq Extensions
public static IQueryable < IPublishedContent > OrderBy ( this IEnumerable < IPublishedContent > list , string predicate )
2012-10-04 03:26:56 +05:00
{
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 ) ;
2013-03-02 01:02:38 +06:00
//we have to wrap the result in another DynamicPublishedContentList so that the OwnersList get's set on
//the individual items. See: http://issues.umbraco.org/issue/U4-1797
return new DynamicPublishedContentList (
dList . Where < DynamicPublishedContent > ( predicate ) )
. AsQueryable < IPublishedContent > ( ) ;
2012-10-04 03:26:56 +05:00
}
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 ) ;
}
2013-03-02 01:02:38 +06:00
public static bool Where ( this IPublishedContent doc , string predicate )
2012-10-04 03:26:56 +05:00
{
if ( doc = = null ) throw new ArgumentNullException ( "doc" ) ;
var dynamicDocumentList = new DynamicPublishedContentList ( ) ;
dynamicDocumentList . Add ( doc . AsDynamicPublishedContent ( ) ) ;
var filtered = dynamicDocumentList . Where < DynamicPublishedContent > ( predicate ) ;
2013-03-02 01:02:38 +06:00
if ( filtered . Count ( ) = = 1 )
2012-10-04 01:31:08 +05:00
{
2012-10-04 03:26:56 +05:00
//this node matches the predicate
return true ;
2012-10-04 01:31:08 +05:00
}
2012-10-04 03:26:56 +05:00
return false ;
2012-10-04 01:31:08 +05:00
}
2012-10-04 03:26:56 +05:00
#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 )
2013-03-02 01:02:38 +06:00
{
var container = content . GetOwnersList ( ) . ToList ( ) ;
2012-10-04 01:31:08 +05:00
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 ) ) ;
}
2012-12-09 03:51:02 +05:00
}
2013-03-02 01:02:38 +06:00
/// <summary>
/// Return the owners collection of the current content item.
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
/// <remarks>
/// If the content item is of type PublishedContentBase we will have a property called OwnersCollection which will
/// be the collection of a resultant set (i.e. from a where clause, a call to Children(), etc...) otherwise it will
/// be the item's siblings. All relates to this issue: http://issues.umbraco.org/issue/U4-1797
/// </remarks>
private static IEnumerable < IPublishedContent > GetOwnersList ( this IPublishedContent content )
{
//Here we need to type check, we need to see if we have a real OwnersCollection list based on the result set
// of a query, otherwise we can only lookup among the item's siblings. All related to this issue here:
// http://issues.umbraco.org/issue/U4-1797
var publishedContentBase = content as IOwnerCollectionAware < IPublishedContent > ;
var ownersList = publishedContentBase ! = null
? publishedContentBase . OwnersCollection
: content . Siblings ( ) ;
return ownersList ;
}
2012-10-04 01:31:08 +05:00
#endregion
#region Is Helpers
2013-09-27 13:12:16 +02:00
public static bool IsDocumentType ( this IPublishedContent content , string docTypeAlias , bool recursive = false )
2012-10-06 23:41:42 +05:00
{
2013-09-27 13:12:16 +02:00
if ( content . DocumentTypeAlias = = docTypeAlias )
return true ;
if ( recursive )
return IsDocumentTypeRecursive ( content , docTypeAlias ) ;
return false ;
}
private static bool IsDocumentTypeRecursive ( IPublishedContent content , string docTypeAlias )
{
var contentTypeService = UmbracoContext . Current . Application . Services . ContentTypeService ;
var type = contentTypeService . GetContentType ( content . DocumentTypeAlias ) ;
while ( type . ParentId > 0 )
{
type = contentTypeService . GetContentType ( type . ParentId ) ;
if ( type . Alias = = docTypeAlias )
return true ;
}
return false ;
2012-10-06 23:41:42 +05:00
}
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 ) ;
2013-03-02 01:02:38 +06:00
}
#region Position in list
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 )
{
var ownersList = content . GetOwnersList ( ) ;
var count = ownersList . Count ( ) ;
return content . IsHelper ( n = > n . Index ( ) = = count - 1 ) ;
}
public static HtmlString IsLast ( this IPublishedContent content , string valueIfTrue )
{
var ownersList = content . GetOwnersList ( ) ;
var count = ownersList . Count ( ) ;
return content . IsHelper ( n = > n . Index ( ) = = count - 1 , valueIfTrue ) ;
}
public static HtmlString IsLast ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
var ownersList = content . GetOwnersList ( ) ;
var count = ownersList . Count ( ) ;
return content . IsHelper ( n = > n . Index ( ) = = count - 1 , valueIfTrue , valueIfFalse ) ;
}
public static bool IsNotLast ( this IPublishedContent content )
{
var ownersList = content . GetOwnersList ( ) ;
var count = ownersList . Count ( ) ;
return ! content . IsHelper ( n = > n . Index ( ) = = count - 1 ) ;
}
public static HtmlString IsNotLast ( this IPublishedContent content , string valueIfTrue )
{
var ownersList = content . GetOwnersList ( ) ;
var count = ownersList . Count ( ) ;
return content . IsHelper ( n = > n . Index ( ) ! = count - 1 , valueIfTrue ) ;
}
public static HtmlString IsNotLast ( this IPublishedContent content , string valueIfTrue , string valueIfFalse )
{
var ownersList = content . GetOwnersList ( ) ;
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 ) ;
}
#endregion
public static bool IsEqual ( this IPublishedContent content , IPublishedContent other )
2012-10-04 01:31:08 +05:00
{
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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsDescendantOrSelf ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsDescendantOrSelf ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static bool IsAncestor ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsAncestor ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsAncestor ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static bool IsAncestorOrSelf ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsAncestorOrSelf ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-01-13 22:36:21 +03:00
public static HtmlString IsAncestorOrSelf ( this IPublishedContent content , IPublishedContent 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 ) ;
}
2013-03-02 01:50:53 +06:00
2012-10-04 01:31:08 +05:00
#endregion
2013-04-16 12:29:58 -02:00
#region Ancestors
2012-10-04 01:31:08 +05:00
2013-04-16 12:29:58 -02:00
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content )
{
return content . AncestorsOrSelf ( false , n = > true ) ;
}
2012-10-04 01:31:08 +05:00
2013-04-16 12:29:58 -02:00
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , int level )
{
return content . AncestorsOrSelf ( false , n = > n . Level < = level ) ;
}
2012-10-04 01:31:08 +05:00
2013-04-16 12:29:58 -02:00
public static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , string nodeTypeAlias )
{
return content . AncestorsOrSelf ( false , n = > n . DocumentTypeAlias = = nodeTypeAlias ) ;
}
2012-10-04 01:31:08 +05:00
2012-10-08 23:32:43 +05:00
internal static IEnumerable < IPublishedContent > Ancestors ( this IPublishedContent content , Func < IPublishedContent , bool > func )
2013-04-16 12:29:58 -02:00
{
return content . AncestorsOrSelf ( false , func ) ;
}
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 ) ;
}
internal static IPublishedContent AncestorOrSelf ( this IPublishedContent content , Func < IPublishedContent , bool > func )
{
if ( func ( content ) )
return content ;
while ( content . Level > 1 ) // while we have a parent, consider the parent
{
content = content . Parent ;
if ( func ( content ) )
return content ;
}
return null ;
}
public static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content )
{
return content . AncestorsOrSelf ( true , n = > true ) ;
}
public static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , int level )
{
return content . AncestorsOrSelf ( true , n = > n . Level < = level ) ;
}
public static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , string nodeTypeAlias )
{
return content . AncestorsOrSelf ( true , n = > n . DocumentTypeAlias = = nodeTypeAlias ) ;
}
internal static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , Func < IPublishedContent , bool > func )
{
return content . AncestorsOrSelf ( true , func ) ;
}
internal static IEnumerable < IPublishedContent > AncestorsOrSelf ( this IPublishedContent content , bool orSelf , Func < IPublishedContent , bool > func )
{
var ancestors = new List < IPublishedContent > ( ) ;
if ( orSelf & & func ( content ) )
ancestors . Add ( content ) ;
while ( content . Level > 1 ) // while we have a parent, consider the parent
{
content = content . Parent ;
if ( func ( content ) )
ancestors . Add ( content ) ;
}
ancestors . Reverse ( ) ;
return ancestors ;
}
#endregion
2012-10-04 01:31:08 +05:00
#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
{
2013-03-02 01:02:38 +06:00
//return content.Children.Map(func, (IPublishedContent n) => n.Children);
return content . Children . FlattenList ( x = > x . Children ) . Where ( func )
. OrderBy ( x = > x . Level ) //ensure its sorted by level and then by sort order
. ThenBy ( x = > x . SortOrder ) ;
2012-10-04 01:31:08 +05:00
}
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 ) ;
}
2013-03-02 01:02:38 +06:00
//var flattenedNodes = content.Children.Map(func, (IPublishedContent n) => n.Children);
var flattenedNodes = content . Children . FlattenList ( n = > n . Children ) . Where ( func ) ;
return thisNode . Concat ( flattenedNodes )
. Select ( dynamicBackingItem = > new DynamicPublishedContent ( dynamicBackingItem ) )
. OrderBy ( x = > x . Level ) //ensure its sorted by level and then by sort order
. ThenBy ( x = > x . SortOrder ) ;
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 )
{
2013-03-02 01:02:38 +06:00
var ownersList = content . GetOwnersList ( ) ;
2012-10-04 01:31:08 +05:00
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 )
{
2013-03-02 01:02:38 +06:00
var ownersList = content . GetOwnersList ( ) ;
2012-10-04 01:31:08 +05:00
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 ) ;
2012-12-09 03:51:02 +05:00
return newIndex ! = - 1
? container . ElementAt ( newIndex )
2012-10-04 01:31:08 +05:00
: 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 )
{
2013-03-02 01:02:38 +06:00
var ownersList = content . GetOwnersList ( ) ;
2012-10-04 01:31:08 +05:00
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 )
{
2013-03-02 01:02:38 +06:00
var ownersList = content . GetOwnersList ( ) ;
2012-10-04 01:31:08 +05:00
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 )
{
2013-03-02 01:02:38 +06:00
var siblings = content . Siblings ( ) ;
2012-10-04 01:31:08 +05:00
2013-03-02 01:02:38 +06:00
var container = siblings . ToList ( ) ;
2012-10-04 01:31:08 +05:00
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 )
2013-03-02 01:02:38 +06:00
{
var siblings = content . Siblings ( ) ;
2012-10-04 01:31:08 +05:00
2013-03-02 01:02:38 +06:00
var container = siblings . ToList ( ) ;
2012-10-04 01:31:08 +05:00
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 ) ) ;
}
2013-03-02 01:02:38 +06:00
/// <summary>
/// Return the items siblings
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public static IEnumerable < IPublishedContent > Siblings ( this IPublishedContent content )
{
//get the root docs if parent is null
return content . Parent = = null
2013-03-19 17:51:55 -01:00
? UmbracoContext . Current . ContentCache . GetAtRoot ( )
2013-03-02 01:02:38 +06:00
: content . Parent . Children ;
}
#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 )
{
2013-03-02 01:02:38 +06:00
return p . Children . OrderBy ( x = > x . SortOrder ) ;
2012-12-09 03:51:02 +05:00
}
2012-10-08 21:55:03 +05:00
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 ( )
2012-12-09 03:51:02 +05:00
? node . Children . Any ( )
? node . Children . ElementAt ( 0 )
: null
: node . Children . FirstOrDefault ( x = > x . DocumentTypeAlias = = nodeTypeAliasFilter ) ;
2012-09-20 12:42:43 +07:00
if ( firstNode = = null )
return new DataTable ( ) ; //no children found
2013-01-31 10:06:25 -01:00
var urlProvider = UmbracoContext . Current . RoutingContext . UrlProvider ;
2012-09-20 12:42:43 +07:00
//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.
( ) = >
2012-12-09 03:51:02 +05:00
{
//create all row data
var tableData = Umbraco . Core . DataTableExtensions . CreateTableData ( ) ;
//loop through each child and create row data for it
2013-03-02 01:02:38 +06:00
foreach ( var n in node . Children . OrderBy ( x = > x . SortOrder ) )
2012-09-20 12:42:43 +07:00
{
2012-12-09 03:51:02 +05:00
if ( ! nodeTypeAliasFilter . IsNullOrWhiteSpace ( ) )
2012-09-20 12:42:43 +07:00
{
2012-12-09 03:51:02 +05:00
if ( n . DocumentTypeAlias ! = nodeTypeAliasFilter )
continue ; //skip this one, it doesn't match the filter
}
2012-09-20 12:42:43 +07:00
2012-12-09 03:51:02 +05:00
var standardVals = new Dictionary < string , object > ( )
2012-09-20 12:42:43 +07:00
{
{ "Id" , n . Id } ,
{ "NodeName" , n . Name } ,
{ "NodeTypeAlias" , n . DocumentTypeAlias } ,
{ "CreateDate" , n . CreateDate } ,
{ "UpdateDate" , n . UpdateDate } ,
{ "CreatorName" , n . CreatorName } ,
{ "WriterName" , n . WriterName } ,
2013-01-31 10:06:25 -01:00
{ "Url" , urlProvider . GetUrl ( n . Id ) }
2012-09-20 12:42:43 +07:00
} ;
2012-12-09 03:51:02 +05:00
var userVals = new Dictionary < string , object > ( ) ;
foreach ( var p in from IPublishedContentProperty p in n . Properties where p . Value ! = null select p )
{
userVals [ p . Alias ] = p . Value ;
2012-09-20 12:42:43 +07:00
}
2012-12-09 03:51:02 +05:00
//add the row data
Umbraco . Core . DataTableExtensions . AddRowData ( tableData , standardVals , userVals ) ;
2012-09-20 12:42:43 +07:00
}
2012-12-09 03:51:02 +05:00
return tableData ;
}
2012-09-20 12:42:43 +07:00
) ;
return dt ;
}
private static Func < string , Dictionary < string , string > > _getPropertyAliasesAndNames ;
2012-12-09 03:51:02 +05:00
2012-09-20 12:42:43 +07:00
/// <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 ; }
}
}
}