diff --git a/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj b/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj new file mode 100644 index 0000000..9af151f --- /dev/null +++ b/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj @@ -0,0 +1,128 @@ + + + + + Debug + AnyCPU + {FE8BE437-8B11-4E49-9B02-F45994E6D723} + Library + Properties + Archetype.Courier + Archetype.Courier + v4.5 + 512 + ..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\UmbracoCms.Core.7.1.2\lib\businesslogic.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\cms.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\interfaces.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\log4net.dll + False + + + ..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.dll + False + + + + + + + ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Core.dll + False + + + lib\Umbraco.Courier.Core.dll + False + + + lib\Umbraco.Courier.DataResolvers.dll + False + + + lib\Umbraco.Courier.Providers.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.DataLayer.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.providers.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Web.UI.dll + False + + + ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.XmlSerializers.dll + False + + + + + Properties\VersionInfo.cs + + + + + + + + + + {7d185d41-4228-4978-acb8-83f9a48ad94f} + Archetype.Umbraco + True + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs b/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs new file mode 100644 index 0000000..e880f85 --- /dev/null +++ b/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Courier.Core; +using Umbraco.Courier.Core.Enums; +using Umbraco.Courier.Core.Helpers; +using Umbraco.Courier.DataResolvers; +using Umbraco.Courier.ItemProviders; + +namespace Archetype.Courier.DataResolvers +{ + public class ArchetypeDataResolver : PropertyDataResolverProvider + { + private enum Direction + { + Extracting, + Packaging + } + + public override string EditorAlias + { + get + { + return Archetype.Constants.PropertyEditorAlias; + } + } + + public override void ExtractingDataType(DataType item) + { + // No longer need to extract the DataType (int) Ids as they now reference the Guid [LK] + } + + public override void ExtractingProperty(Item item, ContentProperty propertyData) + { + ReplacePropertyDataIds(item, propertyData, Direction.Extracting); + } + + public override void PackagingDataType(DataType item) + { + AddDataTypeDependencies(item); + } + + public override void PackagingProperty(Item item, ContentProperty propertyData) + { + ReplacePropertyDataIds(item, propertyData, Direction.Packaging); + } + + private void AddDataTypeDependencies(DataType item) + { + if (item.Prevalues != null && item.Prevalues.Count > 0) + { + var prevalue = item.Prevalues[0]; + if (prevalue.Alias.InvariantEquals(Archetype.Constants.PreValueAlias) && !string.IsNullOrWhiteSpace(prevalue.Value)) + { + var config = JsonConvert.DeserializeObject(prevalue.Value); + + if (config != null && config.Fieldsets != null) + { + foreach (var property in config.Fieldsets.SelectMany(x => x.Properties)) + { + item.Dependencies.Add(property.DataTypeGuid.ToString(), ProviderIDCollection.dataTypeItemProviderGuid); + } + + item.Prevalues[0].Value = JsonConvert.SerializeObject(config, Formatting.None); + } + } + } + } + + private void ReplacePropertyDataIds(Item item, ContentProperty propertyData, Direction direction) + { + if (propertyData != null && propertyData.Value != null) + { + // just look at the amount of dancing around we have to do in order to fake a `PublishedPropertyType`?! + var dataTypeId = PersistenceManager.Default.GetNodeId(propertyData.DataType, NodeObjectTypes.DataType); + var fakePropertyType = this.CreateFakePropertyType(dataTypeId, this.EditorAlias); + + var converter = new Archetype.PropertyConverters.ArchetypeValueConverter(); + var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(fakePropertyType, propertyData.Value, false); + + if (archetype != null) + { + // create a 'fake' provider, as ultimately only the 'Packaging' enum will be referenced. + var fakeItemProvider = new PropertyItemProvider(); + + foreach (var property in archetype.Fieldsets.SelectMany(x => x.Properties)) + { + if (property == null || string.IsNullOrWhiteSpace(property.PropertyEditorAlias)) + continue; + + // create a 'fake' item for Courier to process + var fakeItem = new ContentPropertyData() + { + ItemId = item.ItemId, + Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, this.EditorAlias, property.PropertyEditorAlias, property.Alias }), + Data = new List + { + new ContentProperty + { + Alias = property.Alias, + DataType = PersistenceManager.Default.GetUniqueId(property.DataTypeId, NodeObjectTypes.DataType), + PropertyEditorAlias = property.PropertyEditorAlias, + Value = property.Value + } + } + }; + + if (direction == Direction.Packaging) + { + try + { + // run the 'fake' item through Courier's data resolvers + ResolutionManager.Instance.PackagingItem(fakeItem, fakeItemProvider); + } + catch (Exception ex) + { + LogHelper.Error(string.Concat("Error resolving data value: ", fakeItem.Name), ex); + } + + // pass up the dependencies and resources + item.Dependencies.AddRange(fakeItem.Dependencies); + item.Resources.AddRange(fakeItem.Resources); + + if (fakeItem.Data != null && fakeItem.Data.Any()) + { + var firstDataType = fakeItem.Data.FirstOrDefault(); + if (firstDataType != null) + { + // add a dependency for the property's data-type + property.DataTypeGuid = firstDataType.ToString(); + item.Dependencies.Add(property.DataTypeGuid, ProviderIDCollection.dataTypeItemProviderGuid); + } + } + } + else if (direction == Direction.Extracting) + { + // run the 'fake' item through Courier's data resolvers + ResolutionManager.Instance.ExtractingItem(fakeItem, fakeItemProvider); + + // resolve the property's data-type Id + int identifier; + if (int.TryParse(Dependencies.ConvertIdentifier(property.DataTypeGuid, IdentifierReplaceDirection.FromGuidToNodeId), out identifier)) + property.DataTypeId = dataTypeId; + } + + if (fakeItem.Data != null && fakeItem.Data.Any()) + { + var firstDataType = fakeItem.Data.FirstOrDefault(); + if (firstDataType != null) + { + // set the resolved property data value + property.Value = firstDataType.Value; + } + } + } + + if (item.Name.Contains(string.Concat(this.EditorAlias, ": Nested"))) + { + // if the Archetype is nested, then we only want to return the object itself - not a serialized string + propertyData.Value = archetype; + } + else + { + // if the Archetype is the root/container, then we can serialize it to a string + propertyData.Value = JsonConvert.SerializeObject(archetype, Formatting.None); + } + } + } + } + + private PublishedPropertyType CreateFakePropertyType(int dataTypeId, string propertyEditorAlias) + { + return new PublishedPropertyType(null, new PropertyType(new DataTypeDefinition(-1, propertyEditorAlias) { Id = dataTypeId })); + } + } +} \ No newline at end of file diff --git a/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs b/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..00fbf9d --- /dev/null +++ b/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs @@ -0,0 +1,14 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Archetype.Courier")] +[assembly: AssemblyDescription("A set of tools to support Archetype with Umbraco Courier")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Umbrella Inc Ltd")] +[assembly: AssemblyProduct("Archetype.Courier")] +[assembly: AssemblyCopyright("Copyright \xa9 Lee Kelleher, Umbrella Inc Ltd 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] +[assembly: Guid("6F05C431-ABBF-4D77-9D3D-5AF6C8E318AF")] diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll new file mode 100644 index 0000000..b690a35 Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll differ diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll new file mode 100644 index 0000000..88534f5 Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll differ diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll new file mode 100644 index 0000000..07910fc Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll differ diff --git a/app/Umbraco/Archetype.Courier/packages.config b/app/Umbraco/Archetype.Courier/packages.config new file mode 100644 index 0000000..ee6c9d2 --- /dev/null +++ b/app/Umbraco/Archetype.Courier/packages.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/Umbraco/Umbraco.Archetype.sln b/app/Umbraco/Umbraco.Archetype.sln index bb5fa55..342d893 100644 --- a/app/Umbraco/Umbraco.Archetype.sln +++ b/app/Umbraco/Umbraco.Archetype.sln @@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Tests", "Archetyp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseSizer", "DatabaseSizer\DatabaseSizer.csproj", "{0114C963-C514-49C1-B7AB-DCB1825F498C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Courier", "Archetype.Courier\Archetype.Courier.csproj", "{FE8BE437-8B11-4E49-9B02-F45994E6D723}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,6 +34,10 @@ Global {0114C963-C514-49C1-B7AB-DCB1825F498C}.Debug|Any CPU.Build.0 = Debug|Any CPU {0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.ActiveCfg = Release|Any CPU {0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.Build.0 = Release|Any CPU + {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE