Example #1
0
        // 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
        }