started updating the content type mapping.

This commit is contained in:
Shannon
2015-06-04 16:52:22 +02:00
parent 2fe00d6455
commit 087c07bcbd
8 changed files with 184 additions and 66 deletions
@@ -61,10 +61,89 @@ namespace Umbraco.Tests.Models.Mapping
{
//initialize our content type mapper
var mapper = new ContentTypeModelMapper(new Lazy<PropertyEditorResolver>(() => _propertyEditorResolver.Object));
mapper.ConfigureMappings(configuration, appContext);
mapper.ConfigureMappings(configuration, appContext);
var entityMapper = new EntityModelMapper();
entityMapper.ConfigureMappings(configuration, appContext);
});
}
[Test]
public void ContentTypeDisplay_To_PropertyType()
{
// setup the mocks to return the data we want to test against...
_dataTypeService.Setup(x => x.GetDataTypeDefinitionById(It.IsAny<int>()))
.Returns(Mock.Of<IDataTypeDefinition>(
definition =>
definition.Id == 555
&& definition.PropertyEditorAlias == "myPropertyType"
&& definition.DatabaseType == DataTypeDatabaseType.Nvarchar));
var display = new PropertyTypeDisplay()
{
Id = 1,
Alias = "test",
ContentTypeId = 4,
Description = "testing",
DataTypeId = 555,
Value = "testsdfasdf",
Inherited = false,
Editor = "blah",
SortOrder = 6,
ContentTypeName = "Hello",
Label = "asdfasdf",
GroupId = 8,
Validation = new PropertyTypeValidation()
{
Mandatory = true,
Pattern = "asdfasdfa"
}
};
var result = Mapper.Map<PropertyType>(display);
Assert.AreEqual(1, result.Id);
Assert.AreEqual("test", result.Alias);
Assert.AreEqual("testing", result.Description);
Assert.AreEqual("blah", result.PropertyEditorAlias);
Assert.AreEqual(6, result.SortOrder);
Assert.AreEqual("asdfasdf", result.Name);
Assert.AreEqual(8, result.PropertyGroupId.Value);
}
[Test]
public void ContentGroupDisplay_To_PropertyGroup()
{
var display = new PropertyGroupDisplay()
{
ContentTypeId = 2,
Id = 1,
Inherited = false,
Name = "test",
ParentGroupId = 4,
ParentTabContentTypeNames = new[]
{
"hello", "world"
},
SortOrder = 5,
ParentTabContentTypes = new[]
{
10, 11
}
};
var result = Mapper.Map<PropertyGroup>(display);
Assert.AreEqual(1, result.Id);
Assert.AreEqual("test", result.Name);
Assert.AreEqual(4, result.ParentId);
Assert.AreEqual(5, result.SortOrder);
}
[Test]
public void ContentTypeDisplay_To_IContentType()
{
@@ -97,10 +176,12 @@ namespace Umbraco.Tests.Models.Mapping
Assert.AreEqual(display.Path, result.Path);
Assert.AreEqual(display.Thumbnail, result.Thumbnail);
Assert.AreEqual(display.IsContainer, result.IsContainer);
Assert.AreEqual(display.AllowAsRoot, result.AllowedAsRoot);
//TODO: Now we need to assert all of the more complicated parts
Assert.AreEqual(1, result.PropertyGroups.Count);
Assert.AreEqual(1, result.PropertyGroups[0].PropertyTypes.Count);
Assert.AreEqual(display.AllowedTemplates.Count(), result.AllowedTemplates.Count());
}
[Test]
@@ -152,7 +233,8 @@ namespace Umbraco.Tests.Models.Mapping
{
return new ContentTypeDisplay
{
Alias = "test",
Alias = "test",
AllowAsRoot = true,
AllowedTemplates = new List<EntityBasic>(),
AvailableCompositeContentTypes = new List<EntityBasic>(),
DefaultTemplate = new EntityBasic(){ Alias = "test" },
@@ -165,15 +247,15 @@ namespace Umbraco.Tests.Models.Mapping
ParentId = -1,
Thumbnail = "tree-thumb",
IsContainer = true,
Groups = new List<PropertyTypeGroupDisplay>()
Groups = new List<PropertyGroupDisplay>()
{
new PropertyTypeGroupDisplay
new PropertyGroupDisplay
{
Id = 987,
Name = "Tab 1",
ParentGroupId = -1,
SortOrder = 0,
Inherited = false,
Inherited = false,
Properties = new List<PropertyTypeDisplay>
{
new PropertyTypeDisplay
@@ -59,7 +59,7 @@ namespace Umbraco.Web.Editors
}
public Umbraco.Web.Models.ContentEditing.ContentTypeDisplay GetById(int id)
public ContentTypeDisplay GetById(int id)
{
var ct = Services.ContentTypeService.GetContentType(id);
if (ct == null)
@@ -67,14 +67,14 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var dto = Mapper.Map<IContentType, Umbraco.Web.Models.ContentEditing.ContentTypeDisplay>(ct);
var dto = Mapper.Map<IContentType, ContentTypeDisplay>(ct);
return dto;
}
public Umbraco.Web.Models.ContentEditing.ContentTypeDisplay GetScaffold()
public ContentTypeDisplay GetScaffold()
{
var ct = new ContentType(-1);
var dto = Mapper.Map<IContentType, Umbraco.Web.Models.ContentEditing.ContentTypeDisplay>(ct);
var dto = Mapper.Map<IContentType, ContentTypeDisplay>(ct);
return dto;
}
@@ -102,18 +102,17 @@ namespace Umbraco.Web.Editors
/// <summary>
/// Returns all content type objects
/// </summary>
/// <param name="contentId"></param>
public IEnumerable<ContentTypeBasic> GetAll()
{
var types = Services.ContentTypeService.GetAllContentTypes();
var basics = types.Select(Mapper.Map<IContentType, ContentTypeBasic>);
foreach (var basic in basics)
return basics.Select(basic =>
{
basic.Name = TranslateItem(basic.Name);
basic.Description = TranslateItem(basic.Description);
}
return basics;
return basic;
});
}
/// <summary>
@@ -166,10 +165,10 @@ namespace Umbraco.Web.Editors
var ctService = ApplicationContext.Services.ContentTypeService;
///TODO: warn on content type alias conflicts
///TODO: warn on property alias conflicts
//TODO: warn on content type alias conflicts
//TODO: warn on property alias conflicts
///TODO: Validate the submitted model
//TODO: Validate the submitted model
var ctId = Convert.ToInt32(contentType.Id);
@@ -196,8 +195,7 @@ namespace Umbraco.Web.Editors
contentType.Id = null;
//save as new
IContentType newCt = new ContentType(-1);
Mapper.Map(contentType, newCt);
var newCt = Mapper.Map<IContentType>(contentType);
ctService.Save(newCt);
@@ -17,7 +17,7 @@ namespace Umbraco.Web.Models.ContentEditing
AvailableCompositeContentTypes = new List<EntityBasic>();
AllowedContentTypes = new List<EntityBasic>();
CompositeContentTypes = new List<string>();
Groups = new List<PropertyTypeGroupDisplay>();
Groups = new List<PropertyGroupDisplay>();
}
//name, alias, icon, thumb, desc, inherited from basic
@@ -54,6 +54,6 @@ namespace Umbraco.Web.Models.ContentEditing
//Tabs
[DataMember(Name = "groups")]
public IEnumerable<PropertyTypeGroupDisplay> Groups { get; set; }
public IEnumerable<PropertyGroupDisplay> Groups { get; set; }
}
}
@@ -7,10 +7,10 @@ using System.Threading.Tasks;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "propertyTypeGroup", Namespace = "")]
public class PropertyTypeGroupDisplay
[DataContract(Name = "propertyGroup", Namespace = "")]
public class PropertyGroupDisplay
{
public PropertyTypeGroupDisplay()
public PropertyGroupDisplay()
{
Properties = new List<PropertyTypeDisplay>();
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Models;
@@ -40,53 +41,57 @@ namespace Umbraco.Web.Models.Mapping
//only map id if set to something higher then zero
.ForMember(dto => dto.Id, expression => expression.Condition(display => (Convert.ToInt32(display.Id) > 0)))
.ForMember(dto => dto.AllowedAsRoot, expression => expression.MapFrom(display => display.AllowAsRoot))
.ForMember(dto => dto.CreatorId, expression => expression.Ignore())
.ForMember(dto => dto.Level, expression => expression.Ignore())
.ForMember(dto => dto.CreateDate, expression => expression.Ignore())
.ForMember(dto => dto.UpdateDate, expression => expression.Ignore())
.ForMember(dto => dto.SortOrder, expression => expression.Ignore())
//ignore, we'll do this in after map
.ForMember(dto => dto.PropertyGroups, expression => expression.Ignore())
.AfterMap((source, dest) =>
{
dest.PropertyGroups = new PropertyGroupCollection();
foreach (var groupDisplay in source.Groups.Where(x => !x.Name.IsNullOrWhiteSpace() ) )
foreach (var groupDisplay in source.Groups.Where(x => x.Name.IsNullOrWhiteSpace() == false ) )
{
dest.PropertyGroups.Add(Mapper.Map<PropertyGroup>(groupDisplay));
}
//sync compositions
var current = dest.CompositionAliases();
var current = dest.CompositionAliases().ToArray();
var proposed = source.CompositeContentTypes;
var remove = current.Where(x => !proposed.Contains(x));
var add = proposed.Where(x => !current.Contains(x));
var remove = current.Where(x => proposed.Contains(x) == false);
var add = proposed.Where(x => current.Contains(x) == false);
foreach(var rem in remove)
foreach (var rem in remove)
{
dest.RemoveContentType(rem);
}
foreach(var a in add){
var add_ct = applicationContext.Services.ContentTypeService.GetContentType(a);
if(add_ct != null)
dest.AddContentType(add_ct);
foreach(var a in add)
{
//TODO: Remove N+1 lookup
var addCt = applicationContext.Services.ContentTypeService.GetContentType(a);
if(addCt != null)
dest.AddContentType(addCt);
}
});
config.CreateMap<IContentTypeComposition, string>().ConvertUsing(x => x.Alias);
config.CreateMap<IContentType, ContentTypeDisplay>()
.ForMember(display => display.AllowAsRoot, expression => expression.MapFrom(type => type.AllowedAsRoot))
//Ignore because this is not actually used for content types
.ForMember(display => display.Trashed, expression => expression.Ignore())
//Ignore, we'll do this in after map
.ForMember(dto => dto.AllowedContentTypes, expression => expression.Ignore())
.ForMember(
dto => dto.AvailableCompositeContentTypes,
expression => expression.ResolveUsing(new AvailableCompositeContentTypesResolver(applicationContext)))
.ForMember(
dto => dto.CompositeContentTypes,
expression => expression.MapFrom(dto => dto.ContentTypeComposition) )
expression => expression.MapFrom(dto => dto.ContentTypeComposition))
.ForMember(
dto => dto.CompositeContentTypes,
@@ -94,12 +99,24 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(
dto => dto.Groups,
expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, _propertyEditorResolver)));
expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, _propertyEditorResolver)))
.AfterMap((source, dest) =>
{
//do allowed content types, we need to look them up then assign to a list of entity basic,
//we are doing this manually because ContentTypeSort doesnt have a Name and we want that
var foundCts = applicationContext.Services.ContentTypeService
.GetAllContentTypes(source.AllowedContentTypes.Select(x => Convert.ToInt32(x.Id)).ToArray());
dest.AllowedContentTypes = foundCts.Select(Mapper.Map<EntityBasic>);
});
config.CreateMap<PropertyTypeGroupDisplay, PropertyGroup>()
config.CreateMap<PropertyGroupDisplay, PropertyGroup>()
.ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0))
.ForMember(g => g.CreateDate, expression => expression.Ignore())
.ForMember(g => g.CreateDate, expression => expression.Ignore())
.ForMember(g => g.Key, expression => expression.Ignore())
.ForMember(g => g.CreateDate, expression => expression.Ignore())
.ForMember(g => g.HasIdentity, expression => expression.Ignore())
.ForMember(g => g.UpdateDate, expression => expression.Ignore())
//only map if a parent is actually set
@@ -110,6 +127,8 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(g => g.PropertyTypes, expression => expression.Ignore())
.AfterMap((source, destination) =>
{
destination.PropertyTypes = new PropertyTypeCollection();
foreach (var propertyTypeDisplay in source.Properties.Where(x => x.Label.IsNullOrWhiteSpace() == false ))
{
@@ -125,6 +144,10 @@ namespace Umbraco.Web.Models.Mapping
if (dataType == null) throw new NullReferenceException("No data type found with id " + propertyTypeDisplay.DataTypeId);
return new PropertyType(dataType, propertyTypeDisplay.Alias);
})
.ForMember(type => type.PropertyGroupId, expression => expression.MapFrom(display => new Lazy<int>(() => display.GroupId, LazyThreadSafetyMode.None)))
.ForMember(type => type.Key, expression => expression.Ignore())
.ForMember(type => type.HelpText, expression => expression.Ignore())
.ForMember(type => type.HasIdentity, expression => expression.Ignore())
//ignore because this is set in the ctor
.ForMember(type => type.Alias, expression => expression.Ignore())
//ignore because this is obsolete and shouldn't be used
@@ -47,25 +47,39 @@ namespace Umbraco.Web.Models.Mapping
config.CreateMap<ITemplate, EntityBasic>()
.ForMember(basic => basic.Icon, expression => expression.UseValue("icon-layout"))
.ForMember(basic => basic.Path, expression => expression.UseValue(""))
.ForMember(basic => basic.Path, expression => expression.MapFrom(template => template.Path))
.ForMember(basic => basic.ParentId, expression => expression.UseValue(-1))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
config.CreateMap<IContentType, EntityBasic>()
.ForMember(basic => basic.Icon, expression => expression.UseValue("icon-grid"))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
config.CreateMap<EntityBasic, ITemplate>()
.ConstructUsing(basic => new Template(basic.Name, basic.Alias)
{
Id = Convert.ToInt32(basic.Id),
Key = basic.Key
})
.ForMember(t => t.Path, expression => expression.MapFrom(template => template.Path))
.ForMember(t => t.Id, expression => expression.MapFrom(template => Convert.ToInt32(template.Id)))
.ForMember(x => x.VirtualPath, expression => expression.Ignore())
.ForMember(x => x.CreateDate, expression => expression.Ignore())
.ForMember(x => x.UpdateDate, expression => expression.Ignore())
.ForMember(x => x.Content, expression => expression.Ignore());
config.CreateMap<EntityBasic, ContentTypeSort>()
.ForMember(x => x.Id, expression => expression.MapFrom(entity => new Lazy<int>(() => Convert.ToInt32(entity.Id))))
.ForMember(x => x.SortOrder, expression => expression.Ignore());
config.CreateMap<IContentTypeComposition, EntityBasic>()
.ForMember(basic => basic.Path, expression => expression.UseValue(""))
.ForMember(basic => basic.ParentId, expression => expression.UseValue(-1))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
config.CreateMap<ContentTypeSort, EntityBasic>()
.ForMember(basic => basic.Icon, expression => expression.UseValue("icon-grid"))
.ForMember(basic => basic.Path, expression => expression.UseValue(""))
.ForMember(basic => basic.ParentId, expression => expression.UseValue(-1))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
.ForMember(basic => basic.Icon, expression => expression.UseValue("icon-grid"))
.ForMember(basic => basic.Path, expression => expression.MapFrom(x => x.Path))
.ForMember(basic => basic.ParentId, expression => expression.MapFrom(x => x.ParentId))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
config.CreateMap<SearchResult, EntityBasic>()
//default to document icon
@@ -11,8 +11,9 @@ using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Models.Mapping
{
internal class PropertyTypeGroupResolver : ValueResolver<IContentType, IEnumerable<PropertyTypeGroupDisplay>>
internal class PropertyTypeGroupResolver : ValueResolver<IContentType, IEnumerable<PropertyGroupDisplay>>
{
private readonly ApplicationContext _applicationContext;
private readonly Lazy<PropertyEditorResolver> _propertyEditorResolver;
@@ -24,9 +25,9 @@ namespace Umbraco.Web.Models.Mapping
}
protected override IEnumerable<PropertyTypeGroupDisplay> ResolveCore(IContentType source)
protected override IEnumerable<PropertyGroupDisplay> ResolveCore(IContentType source)
{
var groups = new Dictionary<int,PropertyTypeGroupDisplay>();
var groups = new Dictionary<int,PropertyGroupDisplay>();
//for storing generic properties
var genericProperties = new List<PropertyTypeDisplay>();
@@ -37,7 +38,7 @@ namespace Umbraco.Web.Models.Mapping
{
//process each tab
foreach(var tab in ct.CompositionPropertyGroups){
var group = new PropertyTypeGroupDisplay() { Id = tab.Id, Inherited = true, Name = tab.Name, SortOrder = tab.SortOrder };
var group = new PropertyGroupDisplay() { Id = tab.Id, Inherited = true, Name = tab.Name, SortOrder = tab.SortOrder };
group.ContentTypeId = ct.Id;
group.ParentTabContentTypes = new[] { ct.Id };
group.ParentTabContentTypeNames = new[] { ct.Name };
@@ -60,7 +61,7 @@ namespace Umbraco.Web.Models.Mapping
//pull from own groups
foreach (var ownTab in source.CompositionPropertyGroups)
{
PropertyTypeGroupDisplay group;
PropertyGroupDisplay group;
//if already added
if (groups.ContainsKey(ownTab.Id))
@@ -73,7 +74,7 @@ namespace Umbraco.Web.Models.Mapping
else
{
//if own
group = new PropertyTypeGroupDisplay() { Id = ownTab.Id, Inherited = false, Name = ownTab.Name, SortOrder = ownTab.SortOrder, ContentTypeId = source.Id };
group = new PropertyGroupDisplay() { Id = ownTab.Id, Inherited = false, Name = ownTab.Name, SortOrder = ownTab.SortOrder, ContentTypeId = source.Id };
groups.Add(ownTab.Id, group);
}
@@ -94,7 +95,7 @@ namespace Umbraco.Web.Models.Mapping
if (genericProperties.Any())
{
var genericTab = new PropertyTypeGroupDisplay() { Id = 0, Name = "Generic properties", ParentGroupId = 0, ContentTypeId = source.Id, SortOrder = 999, Inherited = false };
var genericTab = new PropertyGroupDisplay() { Id = 0, Name = "Generic properties", ParentGroupId = 0, ContentTypeId = source.Id, SortOrder = 999, Inherited = false };
groups.Add(0, genericTab);
}
@@ -103,7 +104,7 @@ namespace Umbraco.Web.Models.Mapping
var nameGroupedGroups = groups.Values.GroupBy(x => x.Name);
if (nameGroupedGroups.Any(x => x.Count() > 1))
{
var sortedGroups = new List<PropertyTypeGroupDisplay>();
var sortedGroups = new List<PropertyGroupDisplay>();
foreach (var groupOfGroups in nameGroupedGroups)
{
+1 -1
View File
@@ -306,7 +306,7 @@
<Compile Include="HtmlHelperBackOfficeExtensions.cs" />
<Compile Include="Models\ContentEditing\ContentTypeDisplay.cs" />
<Compile Include="Models\ContentEditing\PropertyTypeDisplay.cs" />
<Compile Include="Models\ContentEditing\PropertyTypeGroupDisplay.cs" />
<Compile Include="Models\ContentEditing\PropertyGroupDisplay.cs" />
<Compile Include="Models\Mapping\AvailableCompositeContentTypesResolver.cs" />
<Compile Include="Models\Mapping\PropertyTypeGroupResolver.cs" />
<Compile Include="Trees\DocumentTypeTreeController.cs" />