Fixes: #U4-1822, #U4-1797 - Is helpers and indexes on result collections using IPublishedContent or DynamicPublishedContent were incorrect,
added unit tests to support issues and fixes.
This commit is contained in:
@@ -716,7 +716,8 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
public IEnumerable<DynamicXml> Descendants(Func<XElement, bool> func)
|
||||
{
|
||||
var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
|
||||
//var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
|
||||
var flattenedNodes = this.BaseElement.Elements().SelectMany(n => n.Elements()).Where(func);
|
||||
return flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n));
|
||||
}
|
||||
public IEnumerable<DynamicXml> DescendantsOrSelf()
|
||||
@@ -725,7 +726,8 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
public IEnumerable<DynamicXml> DescendantsOrSelf(Func<XElement, bool> func)
|
||||
{
|
||||
var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
|
||||
//var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
|
||||
var flattenedNodes = this.BaseElement.Elements().SelectMany(n => n.Elements()).Where(func);
|
||||
var list = new List<DynamicXml>();
|
||||
list.Add(this);
|
||||
list.AddRange(flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n)));
|
||||
|
||||
@@ -5,36 +5,35 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
[Obsolete("This class should not be used, it is just referenced by already obsoleted code and will be removed in the future")]
|
||||
internal static class ExtensionMethods
|
||||
{
|
||||
public static IEnumerable<TSource> Map<TSource>(
|
||||
this IEnumerable<TSource> source,
|
||||
Func<TSource, bool> selectorFunction,
|
||||
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
|
||||
{
|
||||
if (!source.Any())
|
||||
{
|
||||
return source;
|
||||
}
|
||||
// Add what we have to the stack
|
||||
var flattenedList = source.Where(selectorFunction);
|
||||
// Go through the input enumerable looking for children,
|
||||
// and add those if we have them
|
||||
foreach (TSource element in source)
|
||||
{
|
||||
var secondInner = getChildrenFunction(element);
|
||||
if (secondInner.Any())
|
||||
{
|
||||
secondInner = secondInner.Map(selectorFunction, getChildrenFunction);
|
||||
}
|
||||
flattenedList = flattenedList.Concat(secondInner);
|
||||
}
|
||||
return flattenedList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public static IEnumerable<TSource> Map<TSource>(
|
||||
// this IEnumerable<TSource> source,
|
||||
// Func<TSource, bool> selectorFunction,
|
||||
// Func<TSource, IEnumerable<TSource>> getChildrenFunction)
|
||||
//{
|
||||
// if (!source.Any())
|
||||
// {
|
||||
// return source;
|
||||
// }
|
||||
// // Add what we have to the stack
|
||||
// var flattenedList = source.Where(selectorFunction);
|
||||
// // Go through the input enumerable looking for children,
|
||||
// // and add those if we have them
|
||||
// foreach (TSource element in source)
|
||||
// {
|
||||
// var secondInner = getChildrenFunction(element);
|
||||
// if (secondInner.Any())
|
||||
// {
|
||||
// secondInner = secondInner.Map(selectorFunction, getChildrenFunction);
|
||||
// }
|
||||
// flattenedList = flattenedList.Concat(secondInner);
|
||||
// }
|
||||
// return flattenedList;
|
||||
//}
|
||||
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool ContainsAny(this string haystack, IEnumerable<string> needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
@@ -44,6 +43,7 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool ContainsAny(this string haystack, params string[] needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
@@ -53,6 +53,7 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool ContainsAny(this string haystack, StringComparison comparison, IEnumerable<string> needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
@@ -62,6 +63,7 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool ContainsAny(this string haystack, StringComparison comparison, params string[] needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
@@ -71,12 +73,13 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool ContainsInsensitive(this string haystack, string needle)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
return haystack.IndexOf(needle, StringComparison.CurrentCultureIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
[Obsolete("This method should not be used and will be removed in the future")]
|
||||
public static bool HasValue(this string s)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(s);
|
||||
|
||||
@@ -472,6 +472,12 @@ namespace Umbraco.Core.Models
|
||||
return xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by ToDeepXml to recursively add children
|
||||
/// </summary>
|
||||
/// <param name="originalDescendants"></param>
|
||||
/// <param name="currentChildren"></param>
|
||||
/// <param name="currentXml"></param>
|
||||
private static void AddChildXml(
|
||||
IContent[] originalDescendants,
|
||||
IEnumerable<IContent> currentChildren,
|
||||
|
||||
@@ -46,17 +46,18 @@ namespace Umbraco.Tests.PublishedContent
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
</Home>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
<content><![CDATA[some content]]></content>
|
||||
<blah><![CDATA[some content]]></blah>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
@@ -77,6 +78,28 @@ namespace Umbraco.Tests.PublishedContent
|
||||
/// <returns></returns>
|
||||
protected abstract dynamic GetDynamicNode(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Tests the IsLast method with the result set from a Where statement
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter()
|
||||
{
|
||||
var doc = GetDynamicNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Where("Visible"))
|
||||
{
|
||||
if (d.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Single()
|
||||
{
|
||||
@@ -222,11 +245,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var doc = GetDynamicNode(1173);
|
||||
Assert.AreEqual(0, doc.Index());
|
||||
doc = GetDynamicNode(1176);
|
||||
Assert.AreEqual(1, doc.Index());
|
||||
doc = GetDynamicNode(1177);
|
||||
Assert.AreEqual(2, doc.Index());
|
||||
doc = GetDynamicNode(1178);
|
||||
Assert.AreEqual(3, doc.Index());
|
||||
doc = GetDynamicNode(1177);
|
||||
Assert.AreEqual(1, doc.Index());
|
||||
doc = GetDynamicNode(1178);
|
||||
Assert.AreEqual(2, doc.Index());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -372,7 +395,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var casted = (IEnumerable<TDocument>)skip;
|
||||
|
||||
Assert.AreEqual(2, casted.Count());
|
||||
Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[]{1177, 1178}));
|
||||
Assert.IsTrue(casted.Select(x => ((dynamic) x).Id).ContainsAll(new dynamic[] {1178, 1176}));
|
||||
|
||||
}
|
||||
|
||||
@@ -397,7 +420,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var casted = (IEnumerable<TDocument>)take;
|
||||
|
||||
Assert.AreEqual(2, casted.Count());
|
||||
Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1176 }));
|
||||
Assert.IsTrue(casted.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1174, 1177 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -615,7 +638,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Next_Without_Sibling()
|
||||
{
|
||||
var asDynamic = GetDynamicNode(1178);
|
||||
var asDynamic = GetDynamicNode(1176);
|
||||
|
||||
Assert.IsNull(asDynamic.Next());
|
||||
}
|
||||
@@ -637,7 +660,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int) 1174, (int) result.Id);
|
||||
Assert.AreEqual((int)1178, (int)result.Id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using NUnit.Framework;
|
||||
@@ -36,25 +37,26 @@ namespace Umbraco.Tests.PublishedContent
|
||||
<umbracoUrlAlias><![CDATA[this/is/my/alias, anotheralias]]></umbracoUrlAlias>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
<testRecursive><![CDATA[This is the recursive val]]></testRecursive>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
</Home>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<CustomDocument id=""4444"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,4444"" isDoc="""">
|
||||
<CustomDocument id=""4444"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,4444"" isDoc="""">
|
||||
<selectedNodes><![CDATA[1172,1176,1173]]></selectedNodes>
|
||||
</CustomDocument>
|
||||
</Home>
|
||||
@@ -85,7 +87,123 @@ namespace Umbraco.Tests.PublishedContent
|
||||
return doc;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter_Dynamic_Linq()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Where("Visible"))
|
||||
{
|
||||
if (d.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Where(x => x.IsVisible()))
|
||||
{
|
||||
if (d.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Take()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Take(3))
|
||||
{
|
||||
if (d.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Skip()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Skip(1))
|
||||
{
|
||||
if (d.Id != 1176)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Concat()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
|
||||
foreach (var d in doc.Children.Concat(new[] { GetNode(1175), GetNode(4444) }))
|
||||
{
|
||||
if (d.Id != 4444)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(d.IsLast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Descendants_Ordered_Properly()
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
|
||||
var currentLevel = 0;
|
||||
var lastSortOrder = 0;
|
||||
var levelChangesAt = new[] { 1046, 1173, 1174 };
|
||||
|
||||
foreach (var d in doc.DescendantsOrSelf())
|
||||
{
|
||||
if (levelChangesAt.Contains(d.Id))
|
||||
{
|
||||
Assert.Greater(d.Level, currentLevel);
|
||||
currentLevel = d.Level;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(currentLevel, d.Level);
|
||||
Assert.Greater(d.SortOrder, lastSortOrder);
|
||||
}
|
||||
lastSortOrder = d.SortOrder;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Get_Recursive_Val()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
@@ -128,11 +246,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var doc = GetNode(1173);
|
||||
Assert.AreEqual(0, doc.Index());
|
||||
doc = GetNode(1176);
|
||||
Assert.AreEqual(1, doc.Index());
|
||||
doc = GetNode(1177);
|
||||
Assert.AreEqual(2, doc.Index());
|
||||
doc = GetNode(1178);
|
||||
Assert.AreEqual(3, doc.Index());
|
||||
doc = GetNode(1177);
|
||||
Assert.AreEqual(1, doc.Index());
|
||||
doc = GetNode(1178);
|
||||
Assert.AreEqual(2, doc.Index());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -363,7 +481,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Next_Without_Sibling()
|
||||
{
|
||||
var doc = GetNode(1178);
|
||||
var doc = GetNode(1176);
|
||||
|
||||
Assert.IsNull(doc.Next());
|
||||
}
|
||||
@@ -385,7 +503,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int)1174, (int)result.Id);
|
||||
Assert.AreEqual((int)1178, (int)result.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
@@ -214,7 +215,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
}
|
||||
}
|
||||
|
||||
public class PublishedContentWrapper : IPublishedContent
|
||||
public class PublishedContentWrapper : IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
protected IPublishedContent WrappedContent { get; private set; }
|
||||
|
||||
@@ -320,6 +321,46 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
return WrappedContent.GetProperty(alias);
|
||||
}
|
||||
|
||||
private IEnumerable<IPublishedContent> _ownersCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Need to get/set the owner collection when an item is returned from the result set of a query
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Based on this issue here: http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
IEnumerable<IPublishedContent> IOwnerCollectionAware<IPublishedContent>.OwnersCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
var publishedContentBase = WrappedContent as IOwnerCollectionAware<IPublishedContent>;
|
||||
if (publishedContentBase != null)
|
||||
{
|
||||
return publishedContentBase.OwnersCollection;
|
||||
}
|
||||
|
||||
//if the owners collection is null, we'll default to it's siblings
|
||||
if (_ownersCollection == null)
|
||||
{
|
||||
//get the root docs if parent is null
|
||||
_ownersCollection = this.Siblings();
|
||||
}
|
||||
return _ownersCollection;
|
||||
}
|
||||
set
|
||||
{
|
||||
var publishedContentBase = WrappedContent as IOwnerCollectionAware<IPublishedContent>;
|
||||
if (publishedContentBase != null)
|
||||
{
|
||||
publishedContentBase.OwnersCollection = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ownersCollection = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class HomeContentItem : ContentPageContentItem
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Web.Dynamics
|
||||
internal class Grouping<K, T> : IGrouping<K, T> where T : DynamicObject
|
||||
{
|
||||
public K Key { get; set; }
|
||||
public IEnumerable<T> Elements;
|
||||
public IEnumerable<T> Elements { get; set; }
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace Umbraco.Web.Models
|
||||
/// <summary>
|
||||
/// The base dynamic model for views
|
||||
/// </summary>
|
||||
public class DynamicPublishedContent : DynamicObject, IPublishedContent
|
||||
public class DynamicPublishedContent : DynamicObject, IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
protected IPublishedContent PublishedContent { get; private set; }
|
||||
protected internal IPublishedContent PublishedContent { get; private set; }
|
||||
private DynamicPublishedContentList _cachedChildren;
|
||||
private readonly ConcurrentDictionary<string, object> _cachedMemberOutput = new ConcurrentDictionary<string, object>();
|
||||
|
||||
@@ -36,6 +36,46 @@ namespace Umbraco.Web.Models
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IPublishedContent> _ownersCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Need to get/set the owner collection when an item is returned from the result set of a query
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Based on this issue here: http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
IEnumerable<IPublishedContent> IOwnerCollectionAware<IPublishedContent>.OwnersCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
var publishedContentBase = PublishedContent as IOwnerCollectionAware<IPublishedContent>;
|
||||
if (publishedContentBase != null)
|
||||
{
|
||||
return publishedContentBase.OwnersCollection;
|
||||
}
|
||||
|
||||
//if the owners collection is null, we'll default to it's siblings
|
||||
if (_ownersCollection == null)
|
||||
{
|
||||
//get the root docs if parent is null
|
||||
_ownersCollection = this.Siblings();
|
||||
}
|
||||
return _ownersCollection;
|
||||
}
|
||||
set
|
||||
{
|
||||
var publishedContentBase = PublishedContent as IOwnerCollectionAware<IPublishedContent>;
|
||||
if (publishedContentBase != null)
|
||||
{
|
||||
publishedContentBase.OwnersCollection = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ownersCollection = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public dynamic AsDynamic()
|
||||
{
|
||||
return this;
|
||||
|
||||
@@ -11,10 +11,19 @@ using Umbraco.Web.Dynamics;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
public class DynamicPublishedContentList : DynamicObject, IEnumerable<DynamicPublishedContent>
|
||||
/// <summary>
|
||||
/// A collection of DynamicPublishedContent items
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implements many of the dynamic methods required for execution against this list. It also ensures
|
||||
/// that the correct OwnersCollection properties is assigned to the underlying PublishedContentBase object
|
||||
/// of the DynamicPublishedContent item (so long as the IPublishedContent item is actually PublishedContentBase).
|
||||
/// All relates to this issue here: http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
public class DynamicPublishedContentList : DynamicObject, IEnumerable<DynamicPublishedContent>, IEnumerable<IPublishedContent>
|
||||
{
|
||||
internal List<DynamicPublishedContent> Items { get; set; }
|
||||
|
||||
|
||||
public DynamicPublishedContentList()
|
||||
{
|
||||
Items = new List<DynamicPublishedContent>();
|
||||
@@ -22,14 +31,28 @@ namespace Umbraco.Web.Models
|
||||
public DynamicPublishedContentList(IEnumerable<DynamicPublishedContent> items)
|
||||
{
|
||||
var list = items.ToList();
|
||||
//set the owners list for each item
|
||||
list.ForEach(x => SetOwnersList(x, this));
|
||||
Items = list;
|
||||
}
|
||||
|
||||
public DynamicPublishedContentList(IEnumerable<IPublishedContent> items)
|
||||
{
|
||||
var list = items.Select(x => new DynamicPublishedContent(x)).ToList();
|
||||
//set the owners list for each item
|
||||
list.ForEach(x => SetOwnersList(x, this));
|
||||
Items = list;
|
||||
}
|
||||
|
||||
private static void SetOwnersList(IPublishedContent content, IEnumerable<DynamicPublishedContent> list)
|
||||
{
|
||||
var publishedContentBase = content as IOwnerCollectionAware<IPublishedContent>;
|
||||
if (publishedContentBase != null)
|
||||
{
|
||||
publishedContentBase.OwnersCollection = list;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
|
||||
{
|
||||
int index = (int)indexes[0];
|
||||
@@ -134,12 +157,12 @@ namespace Umbraco.Web.Models
|
||||
}
|
||||
if (name == "Take")
|
||||
{
|
||||
result = new DynamicPublishedContentList(this.Take((int)firstArg));
|
||||
result = new DynamicPublishedContentList(this.Take<DynamicPublishedContent>((int)firstArg));
|
||||
return true;
|
||||
}
|
||||
if (name == "Skip")
|
||||
{
|
||||
result = new DynamicPublishedContentList(this.Skip((int)firstArg));
|
||||
result = new DynamicPublishedContentList(this.Skip<DynamicPublishedContent>((int)firstArg));
|
||||
return true;
|
||||
}
|
||||
if (name == "InGroupsOf")
|
||||
@@ -483,14 +506,26 @@ namespace Umbraco.Web.Models
|
||||
return DynamicQueryable.Select(Items.AsQueryable(), predicate, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the adding of an item from the collection
|
||||
/// </summary>
|
||||
/// <param name="publishedContent"></param>
|
||||
public void Add(DynamicPublishedContent publishedContent)
|
||||
{
|
||||
SetOwnersList(publishedContent, this);
|
||||
this.Items.Add(publishedContent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the removal of an item from the collection
|
||||
/// </summary>
|
||||
/// <param name="publishedContent"></param>
|
||||
public void Remove(DynamicPublishedContent publishedContent)
|
||||
{
|
||||
if (this.Items.Contains(publishedContent))
|
||||
{
|
||||
//set owners list to null
|
||||
SetOwnersList(publishedContent, null);
|
||||
this.Items.Remove(publishedContent);
|
||||
}
|
||||
}
|
||||
@@ -503,7 +538,12 @@ namespace Umbraco.Web.Models
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerator<DynamicPublishedContent> GetEnumerator()
|
||||
IEnumerator<IPublishedContent> IEnumerable<IPublishedContent>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<DynamicPublishedContent> GetEnumerator()
|
||||
{
|
||||
return Items.GetEnumerator();
|
||||
}
|
||||
|
||||
12
src/Umbraco.Web/Models/IOwnerCollectionAware.cs
Normal file
12
src/Umbraco.Web/Models/IOwnerCollectionAware.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface describing that the object should be aware of it's containing collection
|
||||
/// </summary>
|
||||
internal interface IOwnerCollectionAware<T>
|
||||
{
|
||||
IEnumerable<T> OwnersCollection { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,17 +9,42 @@ using Umbraco.Web.Templates;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// An abstract base class to use for IPublishedContent which ensures that the Url and Indexed property return values
|
||||
/// are consistently returned.
|
||||
/// </summary>
|
||||
public abstract class PublishedContentBase : IPublishedContent
|
||||
/// <remarks>
|
||||
/// This also ensures that we have an OwnersCollection property so that the IsFirst/IsLast/Index helper methods work
|
||||
/// when referenced inside the result of a collection. http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
public abstract class PublishedContentBase : IPublishedContent, IOwnerCollectionAware<IPublishedContent>
|
||||
{
|
||||
private string _url;
|
||||
private readonly Dictionary<string, object> _resolvePropertyValues = new Dictionary<string, object>();
|
||||
private IEnumerable<IPublishedContent> _ownersCollection;
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Need to get/set the owner collection when an item is returned from the result set of a query
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Based on this issue here: http://issues.umbraco.org/issue/U4-1797
|
||||
/// </remarks>
|
||||
IEnumerable<IPublishedContent> IOwnerCollectionAware<IPublishedContent>.OwnersCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
//if the owners collection is null, we'll default to it's siblings
|
||||
if (_ownersCollection == null)
|
||||
{
|
||||
//get the root docs if parent is null
|
||||
_ownersCollection = this.Siblings();
|
||||
}
|
||||
return _ownersCollection;
|
||||
}
|
||||
set { _ownersCollection = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Url for this content item
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -98,5 +123,6 @@ namespace Umbraco.Web.Models
|
||||
public abstract IPublishedContentProperty GetProperty(string alias);
|
||||
public abstract IPublishedContent Parent { get; }
|
||||
public abstract IEnumerable<IPublishedContent> Children { get; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Web.Models
|
||||
{
|
||||
if (!_initialized)
|
||||
Initialize();
|
||||
return _children;
|
||||
return _children.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data;
|
||||
@@ -272,9 +273,138 @@ namespace Umbraco.Web
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region List Extensions
|
||||
|
||||
#region Linq Wrapping Extensions
|
||||
|
||||
public static IQueryable<IPublishedContent> OrderBy(this IEnumerable<IPublishedContent> list, string predicate)
|
||||
//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)
|
||||
{
|
||||
var dList = new DynamicPublishedContentList(list);
|
||||
return dList.OrderBy<DynamicPublishedContent>(predicate);
|
||||
@@ -283,7 +413,11 @@ namespace Umbraco.Web
|
||||
public static IQueryable<IPublishedContent> Where(this IEnumerable<IPublishedContent> list, string predicate)
|
||||
{
|
||||
var dList = new DynamicPublishedContentList(list);
|
||||
return dList.Where<DynamicPublishedContent>(predicate);
|
||||
//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>();
|
||||
}
|
||||
|
||||
public static IEnumerable<IGrouping<object, IPublishedContent>> GroupBy(this IEnumerable<IPublishedContent> list, string predicate)
|
||||
@@ -336,14 +470,14 @@ namespace Umbraco.Web
|
||||
}
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
public static bool Where(this IPublishedContent doc, string predicate)
|
||||
|
||||
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)
|
||||
if (filtered.Count() == 1)
|
||||
{
|
||||
//this node matches the predicate
|
||||
return true;
|
||||
@@ -359,13 +493,8 @@ namespace Umbraco.Web
|
||||
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();
|
||||
{
|
||||
var container = content.GetOwnersList().ToList();
|
||||
int currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
if (currentIndex != -1)
|
||||
{
|
||||
@@ -376,6 +505,30 @@ namespace Umbraco.Web
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Is Helpers
|
||||
@@ -394,159 +547,145 @@ namespace Umbraco.Web
|
||||
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)
|
||||
#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)
|
||||
{
|
||||
return content.IsHelper(n => n.Id == other.Id);
|
||||
}
|
||||
@@ -782,7 +921,10 @@ namespace Umbraco.Web
|
||||
}
|
||||
private static IEnumerable<IPublishedContent> Descendants(this IPublishedContent content, Func<IPublishedContent, bool> func)
|
||||
{
|
||||
return content.Children.Map(func, (IPublishedContent n) => n.Children);
|
||||
//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);
|
||||
}
|
||||
public static IEnumerable<IPublishedContent> DescendantsOrSelf(this IPublishedContent content, int level)
|
||||
{
|
||||
@@ -805,8 +947,13 @@ namespace Umbraco.Web
|
||||
{
|
||||
thisNode.Add(content);
|
||||
}
|
||||
var flattenedNodes = content.Children.Map(func, (IPublishedContent n) => n.Children);
|
||||
return thisNode.Concat(flattenedNodes).ToList().ConvertAll(dynamicBackingItem => new DynamicPublishedContent(dynamicBackingItem));
|
||||
//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);
|
||||
}
|
||||
return Enumerable.Empty<IPublishedContent>();
|
||||
}
|
||||
@@ -871,10 +1018,7 @@ namespace Umbraco.Web
|
||||
}
|
||||
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 ownersList = content.GetOwnersList();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
var currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
@@ -887,10 +1031,7 @@ namespace Umbraco.Web
|
||||
|
||||
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 ownersList = content.GetOwnersList();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
var currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
@@ -909,10 +1050,7 @@ namespace Umbraco.Web
|
||||
}
|
||||
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 ownersList = content.GetOwnersList();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
var currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
@@ -924,10 +1062,7 @@ namespace Umbraco.Web
|
||||
}
|
||||
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 ownersList = content.GetOwnersList();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
int currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
@@ -945,12 +1080,9 @@ namespace Umbraco.Web
|
||||
}
|
||||
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 siblings = content.Siblings();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
var container = siblings.ToList();
|
||||
var currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
if (currentIndex != -1)
|
||||
{
|
||||
@@ -959,13 +1091,10 @@ namespace Umbraco.Web
|
||||
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 siblings = content.Siblings();
|
||||
|
||||
var container = ownersList.ToList();
|
||||
var container = siblings.ToList();
|
||||
var currentIndex = container.FindIndex(n => n.Id == content.Id);
|
||||
if (currentIndex != -1)
|
||||
{
|
||||
@@ -987,7 +1116,21 @@ namespace Umbraco.Web
|
||||
}
|
||||
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
|
||||
|
||||
/// <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
|
||||
? PublishedContentStoreResolver.Current.PublishedContentStore.GetRootDocuments(UmbracoContext.Current)
|
||||
: content.Parent.Children;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Method to return the Children of the content item
|
||||
@@ -999,7 +1142,7 @@ namespace Umbraco.Web
|
||||
/// </remarks>
|
||||
public static IEnumerable<IPublishedContent> Children(this IPublishedContent p)
|
||||
{
|
||||
return p.Children;
|
||||
return p.Children.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1043,7 +1186,7 @@ namespace Umbraco.Web
|
||||
//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)
|
||||
foreach (var n in node.Children.OrderBy(x => x.SortOrder))
|
||||
{
|
||||
if (!nodeTypeAliasFilter.IsNullOrWhiteSpace())
|
||||
{
|
||||
|
||||
@@ -304,6 +304,7 @@
|
||||
<Compile Include="Media\ImageUrlProviders\ImageUrlProvider.cs" />
|
||||
<Compile Include="Models\DynamicPublishedContent.cs" />
|
||||
<Compile Include="Models\DynamicPublishedContentList.cs" />
|
||||
<Compile Include="Models\IOwnerCollectionAware.cs" />
|
||||
<Compile Include="Models\PartialViewMacroModel.cs" />
|
||||
<Compile Include="Models\PublishedContentBase.cs" />
|
||||
<Compile Include="Mvc\AreaRegistrationExtensions.cs" />
|
||||
|
||||
@@ -1025,8 +1025,9 @@ namespace umbraco.MacroEngines
|
||||
}
|
||||
public DynamicNodeList Descendants(Func<DynamicBackingItem, bool> func)
|
||||
{
|
||||
var flattenedNodes = this.n.ChildrenAsList.Map(func, (DynamicBackingItem n) => { return n.ChildrenAsList; });
|
||||
return new DynamicNodeList(flattenedNodes.ToList().ConvertAll(DynamicBackingItem => new DynamicNode(DynamicBackingItem)));
|
||||
//var flattenedNodes = this.n.ChildrenAsList.Map(func, (DynamicBackingItem n) => { return n.ChildrenAsList; });
|
||||
var flattenedNodes = this.n.ChildrenAsList.FlattenList(item => item.ChildrenAsList).Where(func);
|
||||
return new DynamicNodeList(flattenedNodes.Select(dynamicBackingItem => new DynamicNode(dynamicBackingItem)));
|
||||
}
|
||||
public DynamicNodeList DescendantsOrSelf(int level)
|
||||
{
|
||||
@@ -1049,8 +1050,9 @@ namespace umbraco.MacroEngines
|
||||
{
|
||||
thisNode.Add(this.n);
|
||||
}
|
||||
var flattenedNodes = this.n.ChildrenAsList.Map(func, (DynamicBackingItem n) => { return n.ChildrenAsList; });
|
||||
return new DynamicNodeList(thisNode.Concat(flattenedNodes).ToList().ConvertAll(DynamicBackingItem => new DynamicNode(DynamicBackingItem)));
|
||||
//var flattenedNodes = this.n.ChildrenAsList.Map(func, (DynamicBackingItem n) => { return n.ChildrenAsList; });
|
||||
var flattenedNodes = this.n.ChildrenAsList.FlattenList(item => item.ChildrenAsList).Where(func);
|
||||
return new DynamicNodeList(thisNode.Concat(flattenedNodes).Select(dynamicBackingItem => new DynamicNode(dynamicBackingItem)));
|
||||
}
|
||||
return new DynamicNodeList(new List<DynamicBackingItem>());
|
||||
}
|
||||
|
||||
@@ -3,18 +3,20 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace umbraco.MacroEngines
|
||||
{
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
[Obsolete("This has been superceded by Umbraco.Core.Dynamics.ExtensionMethods.Map method")]
|
||||
[Obsolete("This has been superceded by Umbraco.Core.EnumerableExtensions.FlattenList method")]
|
||||
public static IEnumerable<TSource> Map<TSource>(
|
||||
this IEnumerable<TSource> source,
|
||||
Func<TSource, bool> selectorFunction,
|
||||
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
|
||||
{
|
||||
return Umbraco.Core.Dynamics.ExtensionMethods.Map<TSource>(source, selectorFunction, getChildrenFunction);
|
||||
//return Umbraco.Core.Dynamics.ExtensionMethods.Map<TSource>(source, selectorFunction, getChildrenFunction);
|
||||
return source.FlattenList(getChildrenFunction).Where(selectorFunction);
|
||||
}
|
||||
|
||||
public static DynamicNodeList Random(this DynamicNodeList all, int Min, int Max)
|
||||
|
||||
Reference in New Issue
Block a user