// Umbraco.Code.MapAll -CreatorId -Level -SortOrder -Variations // Umbraco.Code.MapAll -CreateDate -UpdateDate -DeleteDate // Umbraco.Code.MapAll -ContentTypeComposition (done by AfterMapSaveToType) private static void MapSaveToTypeBase <TSource, TSourcePropertyType>(TSource source, IContentTypeComposition target, MapperContext context) where TSource : ContentTypeSave <TSourcePropertyType> where TSourcePropertyType : PropertyTypeBasic { // TODO: not so clean really var isPublishing = target is IContentType; var id = Convert.ToInt32(source.Id); if (id > 0) { target.Id = id; } target.Alias = source.Alias; target.Description = source.Description; target.Icon = source.Icon; target.IsContainer = source.IsContainer; target.IsElement = source.IsElement; target.Key = source.Key; target.Name = source.Name; target.ParentId = source.ParentId; target.Path = source.Path; target.Thumbnail = source.Thumbnail; target.AllowedAsRoot = source.AllowAsRoot; target.AllowedContentTypes = source.AllowedContentTypes.Select((t, i) => new ContentTypeSort(t, i)); if (!(target is IMemberType)) { target.SetVariesBy(ContentVariation.Culture, source.AllowCultureVariant); target.SetVariesBy(ContentVariation.Segment, source.AllowSegmentVariant); } // handle property groups and property types // note that ContentTypeSave has // - all groups, inherited and local; only *one* occurrence per group *name* // - potentially including the generic properties group // - all properties, inherited and local // // also, see PropertyTypeGroupResolver.ResolveCore: // - if a group is local *and* inherited, then Inherited is true // and the identifier is the identifier of the *local* group // // IContentTypeComposition AddPropertyGroup, AddPropertyType methods do some // unique-alias-checking, etc that is *not* compatible with re-mapping everything // the way we do it here, so we should exclusively do it by // - managing a property group's PropertyTypes collection // - managing the content type's PropertyTypes collection (for generic properties) // handle actual groups (non-generic-properties) PropertyGroup[] destOrigGroups = target.PropertyGroups.ToArray(); // local groups IPropertyType[] destOrigProperties = target.PropertyTypes.ToArray(); // all properties, in groups or not var destGroups = new List <PropertyGroup>(); PropertyGroupBasic <TSourcePropertyType>[] sourceGroups = source.Groups.Where(x => x.IsGenericProperties == false).ToArray(); var sourceGroupParentAliases = sourceGroups.Select(x => x.GetParentAlias()).Distinct().ToArray(); foreach (PropertyGroupBasic <TSourcePropertyType> sourceGroup in sourceGroups) { // get the dest group PropertyGroup destGroup = MapSaveGroup(sourceGroup, destOrigGroups, context); // handle local properties IPropertyType[] destProperties = sourceGroup.Properties .Where(x => x.Inherited == false) .Select(x => MapSaveProperty(x, destOrigProperties, context)) .ToArray(); // if the group has no local properties and is not used as parent, skip it, ie sort-of garbage-collect // local groups which would not have local properties anymore if (destProperties.Length == 0 && !sourceGroupParentAliases.Contains(sourceGroup.Alias)) { continue; } // ensure no duplicate alias, then assign the group properties collection EnsureUniqueAliases(destProperties); destGroup.PropertyTypes = new PropertyTypeCollection(isPublishing, destProperties); destGroups.Add(destGroup); } // ensure no duplicate name, then assign the groups collection EnsureUniqueAliases(destGroups); target.PropertyGroups = new PropertyGroupCollection(destGroups); // because the property groups collection was rebuilt, there is no need to remove // the old groups - they are just gone and will be cleared by the repository // handle non-grouped (ie generic) properties PropertyGroupBasic <TSourcePropertyType> genericPropertiesGroup = source.Groups.FirstOrDefault(x => x.IsGenericProperties); if (genericPropertiesGroup != null) { // handle local properties IPropertyType[] destProperties = genericPropertiesGroup.Properties .Where(x => x.Inherited == false) .Select(x => MapSaveProperty(x, destOrigProperties, context)) .ToArray(); // ensure no duplicate alias, then assign the generic properties collection EnsureUniqueAliases(destProperties); target.NoGroupPropertyTypes = new PropertyTypeCollection(isPublishing, destProperties); } // because all property collections were rebuilt, there is no need to remove // some old properties, they are just gone and will be cleared by the repository }