Refactoring the logic in the validation method for when ContentTypes are saved

This commit is contained in:
Morten Christensen
2014-12-11 17:14:01 +01:00
parent 07f9a9700d
commit a446cc224d
4 changed files with 167 additions and 42 deletions

View File

@@ -297,9 +297,11 @@ AND umbracoNode.id <> @id",
//Delete Tabs/Groups by excepting entries from db with entries from collections
var dbPropertyGroups =
Database.Fetch<PropertyTypeGroupDto>("WHERE contenttypeNodeId = @Id", new {Id = entity.Id})
.Select(x => new Tuple<int, string>(x.Id, x.Text));
.Select(x => new Tuple<int, string>(x.Id, x.Text))
.ToList();
var entityPropertyGroups = entity.PropertyGroups.Select(x => new Tuple<int, string>(x.Id, x.Name)).ToList();
var tabs = dbPropertyGroups.Except(entityPropertyGroups);
var tabsToDelete = dbPropertyGroups.Select(x => x.Item1).Except(entityPropertyGroups.Select(x => x.Item1));
var tabs = dbPropertyGroups.Where(x => tabsToDelete.Any(y => y == x.Item1));
//Update Tab name downstream to ensure renaming is done properly
foreach (var propertyGroup in entityPropertyGroups)
{

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
@@ -302,52 +303,30 @@ namespace Umbraco.Core.Services
else
throw new Exception("Composition is neither IContentType nor IMediaType?");
// recursively find all descendants
var compositions = compositionContentType.ContentTypeComposition;
var propertyTypeAliases = compositionContentType.PropertyTypes.Select(x => x.Alias.ToLowerInvariant()).ToArray();
var indirectReferences = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == compositionContentType.Id));
var comparer = new DelegateEqualityComparer<IContentTypeComposition>((x, y) => x.Id == y.Id, x => x.Id);
var descendants = new HashSet<IContentTypeComposition>(comparer);
var stack = new Stack<IContentTypeComposition>();
foreach (var composition in allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == compositionContentType.Id)))
stack.Push(composition);
while (stack.Count > 0)
var dependencies = new HashSet<IContentTypeComposition>(compositions, comparer);
foreach (var indirectReference in indirectReferences)
{
var item = stack.Pop();
descendants.Add(item);
foreach (var composition in allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == item.Id)))
stack.Push(composition);
dependencies.Add(indirectReference);
var directReferences = indirectReference.ContentTypeComposition;
foreach (var directReference in directReferences)
{
if(directReference.Id == compositionContentType.Id || directReference.Alias.Equals(compositionContentType.Alias)) continue;
dependencies.Add(directReference);
}
}
// ensure that no descendant has a property with an alias that is used by content type
var aliases = compositionContentType.PropertyTypes.Select(x => x.Alias.ToLowerInvariant()).ToArray();
foreach (var descendant in descendants)
foreach (var dependency in dependencies)
{
var intersect = descendant.CompositionPropertyTypes.Select(x => x.Alias.ToLowerInvariant()).Intersect(aliases).ToArray();
var contentTypeDependency = allContentTypes.FirstOrDefault(x => x.Alias.Equals(dependency.Alias));
if (contentTypeDependency == null) continue;
var intersect = contentTypeDependency.PropertyTypes.Select(x => x.Alias.ToLowerInvariant()).Intersect(propertyTypeAliases).ToArray();
if (intersect.Length == 0) continue;
var message = string.Format("The following property aliases conflict with descendants : {0}.",
string.Join(", ", intersect));
throw new Exception(message);
}
// find all ancestors
var ancestors = new HashSet<IContentTypeComposition>(comparer);
stack.Clear();
foreach (var composition in compositionContentType.ContentTypeComposition)
stack.Push(composition);
while (stack.Count > 0)
{
var item = stack.Pop();
ancestors.Add(item);
foreach (var composition in item.ContentTypeComposition)
stack.Push(composition);
}
// ensure that no ancestor has a property with an alias that is used by content type
foreach (var ancestor in ancestors)
{
var intersect = ancestor.PropertyTypes.Select(x => x.Alias.ToLowerInvariant()).Intersect(aliases).ToArray();
if (intersect.Length == 0) continue;
var message = string.Format("The following property aliases conflict with ancestors : {0}.",
var message = string.Format("The following PropertyType aliases from the current ContentType conflict with existing PropertyType aliases: {0}.",
string.Join(", ", intersect));
throw new Exception(message);
}