Last active
April 5, 2018 13:43
-
-
Save robertjf/c6d9122d90b4406b19ec to your computer and use it in GitHub Desktop.
NestedContentCreator - generate a NestedContent Property Value based on a Property Type and a list of dictionary items.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using Umbraco.Core; | |
using Umbraco.Core.Models; | |
using Umbraco.Core.Models.Editors; | |
using Umbraco.Core.PropertyEditors; | |
namespace RMS.Extensions.Importers | |
{ | |
public static class NestedContentCreator | |
{ | |
public static List<object> GenerateNestedContentList(PropertyType property, IEnumerable<Dictionary<string, object>> data) | |
{ | |
var contentType = GetContentType(property.DataTypeDefinitionId); | |
List<object> nodes = new List<object>(); | |
foreach (var item in data) | |
{ | |
nodes.Add(GenerateNestedContentItem(contentType, item)); | |
} | |
return nodes; | |
} | |
public static string GenerateNestedContentValue(PropertyType property, IEnumerable<Dictionary<string, object>> data) | |
{ | |
return JsonConvert.SerializeObject(GenerateNestedContentList(property, data)); | |
} | |
public static object GenerateNestedContentItem(IContentType contentType, Dictionary<string, object> propertyData) | |
{ | |
// Update template and populate. | |
var propValues = new JObject(); | |
foreach (var propKey in propertyData.Keys) | |
{ | |
var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); | |
if (propType == null) | |
{ | |
if (propKey != "name") | |
{ | |
// Property missing so just delete the value | |
propValues[propKey] = null; | |
} | |
} | |
else | |
{ | |
// Fetch the property types prevalue | |
var propPreValues = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(propType.DataTypeDefinitionId); | |
// Lookup the property editor | |
var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias); | |
// Create a fake content property data object | |
var contentPropData = new ContentPropertyData( | |
propertyData[propKey] == null ? null : propertyData[propKey].ToString(), propPreValues, | |
new Dictionary<string, object>()); | |
// Get the property editor to do it's conversion | |
var newValue = propEditor.ValueEditor.ConvertEditorToDb(contentPropData, propValues[propKey]); | |
// Add the property | |
propValues[propKey] = (newValue == null) ? null : JToken.FromObject(newValue); | |
} | |
} | |
return propValues; | |
} | |
private static IContentType GetContentType(int propertyDefinitionId) | |
{ | |
var preValueCollection = (PreValueCollection)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( | |
string.Concat("Our.Umbraco.NestedContent.GetPreValuesCollectionByDataTypeId_", propertyDefinitionId), | |
() => ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(propertyDefinitionId)); | |
var preValuesDict = preValueCollection.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value); | |
Guid contentTypeGuid; | |
if (!preValuesDict.ContainsKey("docTypeGuid") || !Guid.TryParse(preValuesDict["docTypeGuid"], out contentTypeGuid)) | |
return null; | |
var contentTypeAlias = GetContentTypeAliasByGuid(Guid.Parse(preValuesDict["docTypeGuid"])); | |
return ApplicationContext.Current.Services.ContentTypeService.GetContentType(contentTypeAlias); | |
} | |
private static string GetContentTypeAliasByGuid(Guid id) | |
{ | |
return (string)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( | |
string.Concat("Our.Umbraco.NestedContent.GetContentTypeAliasByGuid_", id), | |
() => ApplicationContext.Current.DatabaseContext.Database | |
.ExecuteScalar<string>("SELECT [cmsContentType].[alias] FROM [cmsContentType] INNER JOIN [umbracoNode] ON [cmsContentType].[nodeId] = [umbracoNode].[id] WHERE [umbracoNode].[uniqueID] = @0", id)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// showbag is of type IContent. | |
var pt = showbag.PropertyTypes.FirstOrDefault(p => p.Alias == "locations"); | |
// db is an EntityFramework CodeFirst database, with a table rasv_ShowbagStallLocation. | |
// In this example I want to take all locations related to the showbag and import them as a NestedContent list. | |
// Create and serialise the Showbag Locations | |
showbag.SetValue(pt.Alias, NestedContentCreator.GenerateNestedContentValue(pt, | |
db.rasv_ShowbagStallLocation | |
.Where(i => i.ShowbagId == showbagId) | |
.ToList() | |
.Select(location => new Dictionary<string, object> | |
{ | |
{"location", location.ShowbagLocationHTML}, | |
// EnsureEventPrecinct is another method that effectively | |
// maps the EvenTPrecinctId to a Content Node. | |
{"eventPrecinct", EnsureEventPrecinct(location.EventPrecinctId).Id} | |
} | |
))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment