Files
Umbraco-CMS/src/Umbraco.Web/DocumentExtensions.cs
Shannon Deminick a48b996571 Got ChildrenAsTable working as extensions on DynamicDocument with supporting unit tests.
Have updated the ChildrenAsTable code for Node as well to use the same base code, this should
also fix some issues with generating a datatable correctly when a content type is changed, previously
the cache was not cleared for Alias to name mapping.
2012-09-20 12:42:43 +07:00

130 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Web.Routing;
using umbraco.cms.businesslogic;
using Umbraco.Core;
namespace Umbraco.Web
{
/// <summary>
/// Extension methods for IDocument
/// </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>
public static class DocumentExtensions
{
/// <summary>
/// Returns a DataTable object for the IDocument
/// </summary>
/// <param name="d"></param>
/// <param name="nodeTypeAliasFilter"></param>
/// <returns></returns>
public static DataTable ChildrenAsTable(this IDocument d, string nodeTypeAliasFilter = "")
{
return GenerateDataTable(d, nodeTypeAliasFilter);
}
/// <summary>
/// Generates the DataTable for the IDocument
/// </summary>
/// <param name="node"></param>
/// <param name="nodeTypeAliasFilter"> </param>
/// <returns></returns>
private static DataTable GenerateDataTable(IDocument node, string nodeTypeAliasFilter = "")
{
var firstNode = nodeTypeAliasFilter.IsNullOrWhiteSpace()
? node.Children.Any()
? node.Children.ElementAt(0)
: null
: node.Children.FirstOrDefault(x => x.DocumentTypeAlias == nodeTypeAliasFilter);
if (firstNode == null)
return new DataTable(); //no children found
var urlProvider = UmbracoContext.Current.RoutingContext.NiceUrlProvider;
//use new utility class to create table so that we don't have to maintain code in many places, just one
var dt = Umbraco.Core.DataTableExtensions.GenerateDataTable(
//pass in the alias of the first child node since this is the node type we're rendering headers for
firstNode.DocumentTypeAlias,
//pass in the callback to extract the Dictionary<string, string> of all defined aliases to their names
alias => GetPropertyAliasesAndNames(alias),
//pass in a callback to populate the datatable, yup its a bit ugly but it's already legacy and we just want to maintain code in one place.
() =>
{
//create all row data
var tableData = Umbraco.Core.DataTableExtensions.CreateTableData();
//loop through each child and create row data for it
foreach (var n in node.Children)
{
if (!nodeTypeAliasFilter.IsNullOrWhiteSpace())
{
if (n.DocumentTypeAlias != nodeTypeAliasFilter)
continue; //skip this one, it doesn't match the filter
}
var standardVals = new Dictionary<string, object>()
{
{"Id", n.Id},
{"NodeName", n.Name},
{"NodeTypeAlias", n.DocumentTypeAlias},
{"CreateDate", n.CreateDate},
{"UpdateDate", n.UpdateDate},
{"CreatorName", n.CreatorName},
{"WriterName", n.WriterName},
{"Url", urlProvider.GetNiceUrl(n.Id)}
};
var userVals = new Dictionary<string, object>();
foreach (var p in from IDocumentProperty p in n.Properties where p.Value != null select p)
{
userVals[p.Alias] = p.Value;
}
//add the row data
Umbraco.Core.DataTableExtensions.AddRowData(tableData, standardVals, userVals);
}
return tableData;
}
);
return dt;
}
private static Func<string, Dictionary<string, string>> _getPropertyAliasesAndNames;
/// <summary>
/// This is used only for unit tests to set the delegate to look up aliases/names dictionary of a content type
/// </summary>
internal static Func<string, Dictionary<string, string>> GetPropertyAliasesAndNames
{
get
{
return _getPropertyAliasesAndNames ?? (_getPropertyAliasesAndNames = alias =>
{
var userFields = ContentType.GetAliasesAndNames(alias);
//ensure the standard fields are there
var allFields = new Dictionary<string, string>()
{
{"Id", "Id"},
{"NodeName", "NodeName"},
{"NodeTypeAlias", "NodeTypeAlias"},
{"CreateDate", "CreateDate"},
{"UpdateDate", "UpdateDate"},
{"CreatorName", "CreatorName"},
{"WriterName", "WriterName"},
{"Url", "Url"}
};
foreach (var f in userFields.Where(f => !allFields.ContainsKey(f.Key)))
{
allFields.Add(f.Key, f.Value);
}
return allFields;
});
}
set { _getPropertyAliasesAndNames = value; }
}
}
}