Added composite types to the ct mapper
This commit is contained in:
@@ -30,6 +30,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
private Mock<IDataTypeService> _dataTypeService = new Mock<IDataTypeService>();
|
||||
private Mock<PropertyEditorResolver> _propertyEditorResolver;
|
||||
|
||||
private Mock<IEntityService> _entityService = new Mock<IEntityService>();
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
@@ -77,6 +79,7 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
&& definition.PropertyEditorAlias == "myPropertyType"
|
||||
&& definition.DatabaseType == DataTypeDatabaseType.Nvarchar));
|
||||
|
||||
|
||||
var display = CreateSimpleContentTypeDisplay();
|
||||
|
||||
//Act
|
||||
@@ -152,10 +155,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
return new ContentTypeDisplay
|
||||
{
|
||||
Alias = "test",
|
||||
AllowedParentNodeTypes = new List<EntityBasic>(),
|
||||
AllowedTemplates = new List<EntityBasic>(),
|
||||
AvailableContentTypes = new List<EntityBasic>(),
|
||||
AvailableTemplates = new List<EntityBasic>(),
|
||||
AvailableCompositeContentTypes = new List<EntityBasic>(),
|
||||
DefaultTemplate = new EntityBasic(){ Alias = "test" },
|
||||
Description = "hello world",
|
||||
Icon = "tree-icon",
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
//ensure that nothing is marked as dirty
|
||||
contentType.ResetDirtyProperties(false);
|
||||
|
||||
contentType.SetDefaultTemplate(new Template("Textpage", "textpage"));
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
//initialize collections so at least their never null
|
||||
AllowedTemplates = new List<EntityBasic>();
|
||||
AvailableTemplates = new List<EntityBasic>();
|
||||
AvailableContentTypes = new List<EntityBasic>();
|
||||
AllowedParentNodeTypes = new List<EntityBasic>();
|
||||
AvailableCompositeContentTypes = new List<EntityBasic>();
|
||||
AllowedContentTypes = new List<EntityBasic>();
|
||||
CompositeContentTypes = new List<EntityBasic>();
|
||||
Groups = new List<PropertyTypeGroupDisplay>();
|
||||
}
|
||||
@@ -28,22 +27,19 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
[DataMember(Name = "allowedTemplates")]
|
||||
public IEnumerable<EntityBasic> AllowedTemplates { get; set; }
|
||||
|
||||
[DataMember(Name = "availableTemplates")]
|
||||
public IEnumerable<EntityBasic> AvailableTemplates { get; set; }
|
||||
|
||||
[DataMember(Name = "defaultTemplate")]
|
||||
public EntityBasic DefaultTemplate { get; set; }
|
||||
|
||||
|
||||
// Allowed parent node types (can include root)
|
||||
[DataMember(Name = "allowedParentNodeTypes")]
|
||||
public IEnumerable<EntityBasic> AllowedParentNodeTypes { get; set; }
|
||||
// Allowed parent node types (could include root?)
|
||||
[DataMember(Name = "allowedContentTypes")]
|
||||
public IEnumerable<EntityBasic> AllowedContentTypes { get; set; }
|
||||
|
||||
|
||||
//List view
|
||||
[DataMember(Name = "enableListView")]
|
||||
public bool EnableListView { get; set; }
|
||||
|
||||
//we might not need this...
|
||||
[DataMember(Name = "allowedAtRoot")]
|
||||
public bool AllowedAsRoot { get; set; }
|
||||
|
||||
@@ -51,8 +47,8 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
[DataMember(Name = "compositeContentTypes")]
|
||||
public IEnumerable<EntityBasic> CompositeContentTypes { get; set; }
|
||||
|
||||
[DataMember(Name = "availableContentTypes")]
|
||||
public IEnumerable<EntityBasic> AvailableContentTypes { get; set; }
|
||||
[DataMember(Name = "availableCompositeContentTypes")]
|
||||
public IEnumerable<EntityBasic> AvailableCompositeContentTypes { get; set; }
|
||||
|
||||
|
||||
//Tabs
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
internal class AvailableCompositeContentTypesResolver : ValueResolver<IContentType, IEnumerable<EntityBasic>>
|
||||
{
|
||||
private ApplicationContext _context;
|
||||
private bool _mediaType;
|
||||
internal AvailableCompositeContentTypesResolver(ApplicationContext context, bool mediaType = false)
|
||||
{
|
||||
_context = context;
|
||||
_mediaType = mediaType;
|
||||
}
|
||||
|
||||
protected override IEnumerable<EntityBasic> ResolveCore(IContentType source)
|
||||
{
|
||||
//below is all ported from the old doc type editor and comes with the same weaknesses /insanity
|
||||
|
||||
//get all types
|
||||
var allContentTypes = _mediaType
|
||||
? _context.Services.ContentTypeService.GetAllMediaTypes().Cast<IContentTypeComposition>().ToArray()
|
||||
: _context.Services.ContentTypeService.GetAllContentTypes().Cast<IContentTypeComposition>().ToArray();
|
||||
|
||||
// note: there are many sanity checks missing here and there ;-((
|
||||
// make sure once and for all
|
||||
//if (allContentTypes.Any(x => x.ParentId > 0 && x.ContentTypeComposition.Any(y => y.Id == x.ParentId) == false))
|
||||
// throw new Exception("A parent does not belong to a composition.");
|
||||
|
||||
// find out if any content type uses this content type
|
||||
var isUsing = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == source.Id)).ToArray();
|
||||
if (isUsing.Length > 0)
|
||||
{
|
||||
//if already in use a composition, do not allow any composited types
|
||||
return new List<EntityBasic>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it is not used then composition is possible
|
||||
// hashset guarantees unicity on Id
|
||||
var list = new HashSet<IContentTypeComposition>(new DelegateEqualityComparer<IContentTypeComposition>(
|
||||
(x, y) => x.Id == y.Id,
|
||||
x => x.Id));
|
||||
|
||||
// usable types are those that are top-level
|
||||
var usableContentTypes = allContentTypes
|
||||
.Where(x => x.ContentTypeComposition.Any() == false).ToArray();
|
||||
foreach (var x in usableContentTypes)
|
||||
list.Add(x);
|
||||
|
||||
// indirect types are those that we use, directly or indirectly
|
||||
var indirectContentTypes = GetIndirect(source).ToArray();
|
||||
foreach (var x in indirectContentTypes)
|
||||
list.Add(x);
|
||||
|
||||
// directContentTypes are those we use directly
|
||||
// they are already in indirectContentTypes, no need to add to the list
|
||||
var directContentTypes = source.ContentTypeComposition.ToArray();
|
||||
|
||||
var enabled = usableContentTypes.Select(x => x.Id) // those we can use
|
||||
.Except(indirectContentTypes.Select(x => x.Id)) // except those that are indirectly used
|
||||
.Union(directContentTypes.Select(x => x.Id)) // but those that are directly used
|
||||
.Where(x => x != source.ParentId) // but not the parent
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
var wtf = new List<EntityBasic>();
|
||||
foreach (var contentType in list.OrderBy(x => x.Name).Where(x => x.Id != source.Id))
|
||||
wtf.Add(Mapper.Map<IContentTypeComposition, EntityBasic>(contentType));
|
||||
|
||||
return wtf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<IContentTypeComposition> GetIndirect(IContentTypeComposition ctype)
|
||||
{
|
||||
// hashset guarantees unicity on Id
|
||||
var all = new HashSet<IContentTypeComposition>(new DelegateEqualityComparer<IContentTypeComposition>(
|
||||
(x, y) => x.Id == y.Id,
|
||||
x => x.Id));
|
||||
|
||||
var stack = new Stack<IContentTypeComposition>();
|
||||
|
||||
foreach (var x in ctype.ContentTypeComposition)
|
||||
stack.Push(x);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var x = stack.Pop();
|
||||
all.Add(x);
|
||||
foreach (var y in x.ContentTypeComposition)
|
||||
stack.Push(y);
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,15 +58,13 @@ namespace Umbraco.Web.Models.Mapping
|
||||
//Ignore because this is not actually used for content types
|
||||
.ForMember(display => display.Trashed, expression => expression.Ignore())
|
||||
|
||||
//Ignore for now, this will need to be manually mapped or mapped with a resolver
|
||||
// since there is no source property to map from
|
||||
.ForMember(display => display.AvailableContentTypes, expression => expression.Ignore())
|
||||
|
||||
//Ignore for now, this will need to be manually mapped or mapped with a resolver
|
||||
// since there is no source property to map from
|
||||
.ForMember(display => display.AvailableTemplates, expression => expression.Ignore())
|
||||
.ForMember(
|
||||
dto => dto.AvailableCompositeContentTypes,
|
||||
expression => expression.ResolveUsing(new AvailableCompositeContentTypesResolver(applicationContext)))
|
||||
|
||||
|
||||
.ForMember(display => display.EnableListView, expression => expression.MapFrom(type => type.IsContainer))
|
||||
|
||||
.ForMember(
|
||||
dto => dto.Groups,
|
||||
expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, _propertyEditorResolver)));
|
||||
|
||||
@@ -52,6 +52,12 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
|
||||
.ForMember(x => x.AdditionalData, 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<SearchResult, EntityBasic>()
|
||||
//default to document icon
|
||||
.ForMember(x => x.Icon, expression => expression.Ignore())
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace Umbraco.Web.Models.Mapping
|
||||
protected override IEnumerable<PropertyTypeGroupDisplay> ResolveCore(IContentType source)
|
||||
{
|
||||
var groups = new List<PropertyTypeGroupDisplay>();
|
||||
|
||||
var propGroups = source.CompositionPropertyGroups.ToArray();
|
||||
|
||||
var genericGroup = new PropertyTypeGroupDisplay() { Name = "properties", Id = 0, ParentGroupId = 0 };
|
||||
|
||||
@@ -307,6 +307,7 @@
|
||||
<Compile Include="Models\ContentEditing\ContentTypeDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyTypeDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyTypeGroupDisplay.cs" />
|
||||
<Compile Include="Models\Mapping\AvailableCompositeContentTypesResolver.cs" />
|
||||
<Compile Include="Models\Mapping\PropertyTypeGroupResolver.cs" />
|
||||
<Compile Include="Trees\DocumentTypeTreeController.cs" />
|
||||
<Compile Include="UmbracoDefaultOwinStartup.cs" />
|
||||
|
||||
Reference in New Issue
Block a user