コード例 #1
0
        private static PropertyGroup MapSaveGroup <TPropertyType>(PropertyGroupBasic <TPropertyType> sourceGroup,
                                                                  IEnumerable <PropertyGroup> destOrigGroups, MapperContext context)
            where TPropertyType : PropertyTypeBasic
        {
            PropertyGroup destGroup;

            if (sourceGroup.Id > 0)
            {
                // update an existing group
                // ensure it is still there, then map/update
                destGroup = destOrigGroups.FirstOrDefault(x => x.Id == sourceGroup.Id);
                if (destGroup != null)
                {
                    context.Map(sourceGroup, destGroup);
                    return(destGroup);
                }

                // force-clear the ID as it does not match anything
                sourceGroup.Id = 0;
            }

            // insert a new group, or update an existing group that has
            // been deleted in the meantime and we need to re-create
            // map/create
            destGroup = context.Map <PropertyGroup>(sourceGroup);
            return(destGroup);
        }
コード例 #2
0
        /// <summary>
        ///     Adds errors to the model state if any invalid aliases are found then throws an error response if there are errors
        /// </summary>
        /// <param name="contentTypeSave"></param>
        /// <param name="duplicatePropertyTypeAliases"></param>
        /// <param name="invalidPropertyGroupAliases"></param>
        /// <returns></returns>
        private void AddCompositionValidationErrors <TContentTypeSave, TPropertyType>(TContentTypeSave contentTypeSave,
                                                                                      IEnumerable <string>?duplicatePropertyTypeAliases, IEnumerable <string>?invalidPropertyGroupAliases)
            where TContentTypeSave : ContentTypeSave <TPropertyType>
            where TPropertyType : PropertyTypeBasic
        {
            if (duplicatePropertyTypeAliases is not null)
            {
                foreach (var propertyTypeAlias in duplicatePropertyTypeAliases)
                {
                    // Find the property type relating to these
                    TPropertyType property = contentTypeSave.Groups.SelectMany(x => x.Properties)
                                             .Single(x => x.Alias == propertyTypeAlias);
                    PropertyGroupBasic <TPropertyType> group =
                        contentTypeSave.Groups.Single(x => x.Properties.Contains(property));
                    var propertyIndex = group.Properties.IndexOf(property);
                    var groupIndex    = contentTypeSave.Groups.IndexOf(group);

                    var key = $"Groups[{groupIndex}].Properties[{propertyIndex}].Alias";
                    ModelState.AddModelError(key, "Duplicate property aliases aren't allowed between compositions");
                }
            }

            if (invalidPropertyGroupAliases is not null)
            {
                foreach (var propertyGroupAlias in invalidPropertyGroupAliases)
                {
                    // Find the property group relating to these
                    PropertyGroupBasic <TPropertyType> group =
                        contentTypeSave.Groups.Single(x => x.Alias == propertyGroupAlias);
                    var groupIndex = contentTypeSave.Groups.IndexOf(group);
                    var key        = $"Groups[{groupIndex}].Name";
                    ModelState.AddModelError(key, "Different group types aren't allowed between compositions");
                }
            }
        }
コード例 #3
0
 // Umbraco.Code.MapAll -CreateDate -UpdateDate -DeleteDate -Key -PropertyTypes
 private static void Map(PropertyGroupBasic <MemberPropertyTypeBasic> source, PropertyGroup target, MapperContext context)
 {
     if (source.Id > 0)
     {
         target.Id = source.Id;
     }
     target.Name      = source.Name;
     target.SortOrder = source.SortOrder;
 }
コード例 #4
0
 // Umbraco.Code.MapAll -CreateDate -UpdateDate -DeleteDate -Key -PropertyTypes
 private static void Map(PropertyGroupBasic <PropertyTypeBasic> source, PropertyGroup target, MapperContext context)
 {
     if (source.Id > 0)
     {
         target.Id = source.Id;
     }
     target.Key       = source.Key;
     target.Type      = source.Type;
     target.Name      = source.Name;
     target.Alias     = source.Alias;
     target.SortOrder = source.SortOrder;
 }
コード例 #5
0
        // Umbraco.Code.MapAll -ContentTypeId -ParentTabContentTypes -ParentTabContentTypeNames
        private static void Map(PropertyGroupBasic <MemberPropertyTypeBasic> source, PropertyGroupDisplay <MemberPropertyTypeDisplay> target, MapperContext context)
        {
            if (source.Id > 0)
            {
                target.Id = source.Id;
            }

            target.Inherited = source.Inherited;
            target.Name      = source.Name;
            target.SortOrder = source.SortOrder;

            target.Properties = context.MapEnumerable <MemberPropertyTypeBasic, MemberPropertyTypeDisplay>(source.Properties);
        }
コード例 #6
0
 // Umbraco.Code.MapAll -ContentTypeId -ParentTabContentTypes -ParentTabContentTypeNames
 private static void Map(PropertyGroupBasic <PropertyTypeBasic> source, PropertyGroupDisplay <PropertyTypeDisplay> target, MapperContext context)
 {
     target.Inherited = source.Inherited;
     if (source.Id > 0)
     {
         target.Id = source.Id;
     }
     target.Key        = source.Key;
     target.Type       = source.Type;
     target.Name       = source.Name;
     target.Alias      = source.Alias;
     target.SortOrder  = source.SortOrder;
     target.Properties = context.MapEnumerable <PropertyTypeBasic, PropertyTypeDisplay>(source.Properties);
 }
コード例 #7
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
        }
コード例 #8
0
        public void Can_Perform_Update_On_ContentTypeRepository_After_Model_Mapping()
        {
            // Arrange
            IScopeProvider provider = ScopeProvider;

            using (IScope scope = provider.CreateScope())
            {
                ContentTypeRepository repository = ContentTypeRepository;

                // Act
                IContentType contentType = repository.Get(_textpageContentType.Id);

                // there is NO mapping from display to contentType, but only from save
                // to contentType, so if we want to test, let's to it properly!
                DocumentTypeDisplay display = Mapper.Map <DocumentTypeDisplay>(contentType);
                DocumentTypeSave    save    = MapToContentTypeSave(display);

                // modify...
                save.Thumbnail = "Doc2.png";
                PropertyGroupBasic <PropertyTypeBasic> contentGroup = save.Groups.Single(x => x.Name == "Content");
                contentGroup.Properties = contentGroup.Properties.Concat(new[]
                {
                    new PropertyTypeBasic
                    {
                        Alias       = "subtitle",
                        Label       = "Subtitle",
                        Description = "Optional Subtitle",
                        Validation  = new PropertyTypeValidation
                        {
                            Mandatory = false,
                            Pattern   = string.Empty
                        },
                        SortOrder  = 1,
                        DataTypeId = -88,
                        LabelOnTop = true
                    }
                });

                IContentType mapped = Mapper.Map(save, contentType);

                // just making sure
                Assert.AreEqual(mapped.Thumbnail, "Doc2.png");
                Assert.IsTrue(mapped.PropertyTypes.Any(x => x.Alias == "subtitle"));
                Assert.IsTrue(mapped.PropertyTypes.Single(x => x.Alias == "subtitle").LabelOnTop);

                repository.Save(mapped);

                bool dirty = mapped.IsDirty();

                // re-get
                contentType = repository.Get(_textpageContentType.Id);

                // Assert
                Assert.That(contentType.HasIdentity, Is.True);
                Assert.That(dirty, Is.False);
                Assert.That(contentType.Thumbnail, Is.EqualTo("Doc2.png"));
                Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "subtitle"), Is.True);

                Assert.That(contentType.PropertyTypes.Single(x => x.Alias == "subtitle").LabelOnTop, Is.True);

                foreach (IPropertyType propertyType in contentType.PropertyTypes)
                {
                    Assert.IsTrue(propertyType.HasIdentity);
                    Assert.Greater(propertyType.Id, 0);
                }
            }
        }
コード例 #9
0
 public static string?GetParentAlias(this PropertyGroupBasic propertyGroup)
 => PropertyGroupExtensions.GetParentAlias(propertyGroup.Alias);
コード例 #10
0
    public void PropertyGroupBasic_To_PropertyGroup()
    {
        var dataType = new DataType(Services.GetRequiredService <LabelPropertyEditor>(), _serializer)
        {
            Name = "TODO"
        };

        _dataTypeService.Save(dataType);

        var basic = new PropertyGroupBasic <PropertyTypeBasic>
        {
            Id         = 222,
            Alias      = "group1",
            Name       = "Group 1",
            SortOrder  = 1,
            Properties = new[]
            {
                new PropertyTypeBasic
                {
                    Id          = 33,
                    SortOrder   = 1,
                    Alias       = "prop1",
                    Description = "property 1",
                    DataTypeId  = dataType.Id,
                    GroupId     = 222,
                    Label       = "Prop 1",
                    Validation  = new PropertyTypeValidation {
                        Mandatory = true, Pattern = null
                    }
                },
                new PropertyTypeBasic
                {
                    Id          = 34,
                    SortOrder   = 2,
                    Alias       = "prop2",
                    Description = "property 2",
                    DataTypeId  = dataType.Id,
                    GroupId     = 222,
                    Label       = "Prop 2",
                    Validation  = new PropertyTypeValidation {
                        Mandatory = false, Pattern = null
                    }
                }
            }
        };

        var contentType = new DocumentTypeSave
        {
            Id               = 0,
            ParentId         = -1,
            Alias            = "alias",
            AllowedTemplates = Enumerable.Empty <string>(),
            Groups           = new[] { basic }
        };

        // proper group properties mapping takes place when mapping the content type,
        // not when mapping the group - because of inherited properties and such
        // var result = Mapper.Map<PropertyGroup>(basic);
        var result = _sut.Map <IContentType>(contentType).PropertyGroups[0];

        Assert.AreEqual(basic.Name, result.Name);
        Assert.AreEqual(basic.Id, result.Id);
        Assert.AreEqual(basic.SortOrder, result.SortOrder);
        Assert.AreEqual(basic.Properties.Count(), result.PropertyTypes.Count());
    }