/// <summary>
        /// Used to check if any property type was changed between variant/invariant
        /// </summary>
        /// <param name="contentType"></param>
        /// <returns></returns>
        internal static bool WasPropertyTypeVariationChanged(this IContentTypeBase contentType, out IReadOnlyCollection <string> aliases)
        {
            var a = new List <string>();

            // property variation change?
            var hasAnyPropertyVariationChanged = contentType.PropertyTypes.Any(propertyType =>
            {
                if (!(propertyType is IRememberBeingDirty dirtyProperty))
                {
                    throw new Exception("oops");
                }

                // skip new properties
                //TODO: This used to be WasPropertyDirty("HasIdentity") but i don't think that actually worked for detecting new entities this does seem to work properly
                var isNewProperty = dirtyProperty.WasPropertyDirty("Id");
                if (isNewProperty)
                {
                    return(false);
                }

                // variation change?
                var dirty = dirtyProperty.WasPropertyDirty("Variations");
                if (dirty)
                {
                    a.Add(propertyType.Alias);
                }

                return(dirty);
            });

            aliases = a;
            return(hasAnyPropertyVariationChanged);
        }
示例#2
0
        // Umbraco.Code.MapAll -Blueprints
        private void Map(IContentTypeBase source, ContentTypeBasic target, string entityType)
        {
            target.Udi          = Udi.Create(entityType, source.Key);
            target.Alias        = source.Alias;
            target.CreateDate   = source.CreateDate;
            target.Description  = source.Description;
            target.Icon         = source.Icon;
            target.IconFilePath = target.IconIsClass
                ? string.Empty
                : $"{_globalSettings.GetBackOfficePath(_hostingEnvironment).EnsureEndsWith("/")}images/umbraco/{source.Icon}";

            target.Trashed           = source.Trashed;
            target.Id                = source.Id;
            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.ThumbnailFilePath = target.ThumbnailIsClass
                ? string.Empty
                : _hostingEnvironment.ToAbsolute("~/umbraco/images/thumbnails/" + source.Thumbnail);
            target.UpdateDate = source.UpdateDate;
        }
        public IContentTypeBase SetAccessibilityProperties(IContentTypeBase contentTypeBase, string transitionAlias, string oldPropAlias)
        {
            if (_isMemberType)
            {
                var memberType = contentTypeBase as IMemberType;

                if (memberType == null)
                {
                    throw new System.Exception("wrong type");
                }

                memberType.SetMemberCanEditProperty(transitionAlias, memberType.MemberCanEditProperty(oldPropAlias));
                memberType.SetMemberCanViewProperty(transitionAlias, memberType.MemberCanViewProperty(oldPropAlias));

                return(memberType);
            }

            //for content there is no need to set accessibility properties
            else
            {
                if (!(contentTypeBase is IContentType))
                {
                    throw new System.Exception("wrong type");
                }

                return(contentTypeBase);
            }
        }
示例#4
0
        /// <summary>
        /// Converts a content type to a jsonPayload object
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="isDeleted">if the item was deleted</param>
        /// <returns></returns>
        internal static JsonPayload FromContentType(IContentTypeBase contentType, bool isDeleted = false)
        {
            var contentTypeService = (ContentTypeService)ApplicationContext.Current.Services.ContentTypeService;
            var payload            = new JsonPayload
            {
                Alias           = contentType.Alias,
                Id              = contentType.Id,
                PropertyTypeIds = contentType.PropertyTypes.Select(x => x.Id).ToArray(),
                //either IContentType or IMediaType or IMemberType
                Type = (contentType is IContentType)
                    ? typeof(IContentType).Name
                    : (contentType is IMediaType)
                        ? typeof(IMediaType).Name
                        : typeof(IMemberType).Name,
                DescendantPayloads       = contentTypeService.GetDescendants(contentType).Select(x => FromContentType(x)).ToArray(),
                WasDeleted               = isDeleted,
                PropertyRemoved          = contentType.WasPropertyDirty("HasPropertyTypeBeenRemoved"),
                AliasChanged             = contentType.WasPropertyDirty("Alias"),
                PropertyTypeAliasChanged = contentType.PropertyTypes.Any(x => x.WasPropertyDirty("Alias")),
                IsNew = contentType.WasPropertyDirty("HasIdentity")
            };


            return(payload);
        }
示例#5
0
        private static ContentType MapContentTypeBase(IContentTypeBase contentTypeBase)
        {
            var type = new ContentType();

            MapContentTypeBase(contentTypeBase, type);
            return(type);
        }
        /// <summary>
        /// Converts a content type to a jsonPayload object
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="isDeleted">if the item was deleted</param>
        /// <returns></returns>
        private static JsonPayload FromContentType(IContentTypeBase contentType, bool isDeleted = false)
        {
            var payload = new JsonPayload
            {
                Alias           = contentType.Alias,
                Id              = contentType.Id,
                PropertyTypeIds = contentType.PropertyTypes.Select(x => x.Id).ToArray(),
                //either IContentType or IMediaType or IMemberType
                Type = (contentType is IContentType)
                        ? typeof(IContentType).Name
                        : (contentType is IMediaType)
                        ? typeof(IMediaType).Name
                        : typeof(IMemberType).Name,
                DescendantPayloads = contentType.Descendants().Select(x => FromContentType(x)).ToArray(),
                WasDeleted         = isDeleted
            };
            //here we need to check if the alias of the content type changed or if one of the properties was removed.
            var dirty = contentType as IRememberBeingDirty;

            if (dirty != null)
            {
                payload.PropertyRemoved = dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved");
                payload.AliasChanged    = dirty.WasPropertyDirty("Alias");
                payload.IsNew           = dirty.WasPropertyDirty("HasIdentity");
            }
            return(payload);
        }
示例#7
0
        public ContentTypeDto BuildContentTypeDto(IContentTypeBase entity)
        {
            Guid nodeObjectType;

            if (entity is IContentType)
            {
                nodeObjectType = Constants.ObjectTypes.DocumentTypeGuid;
            }
            else if (entity is IMediaType)
            {
                nodeObjectType = Constants.ObjectTypes.MediaTypeGuid;
            }
            else if (entity is IMemberType)
            {
                nodeObjectType = Constants.ObjectTypes.MemberTypeGuid;
            }
            else
            {
                throw new Exception("Invalid entity.");
            }

            var contentTypeDto = new ContentTypeDto
            {
                Alias       = entity.Alias,
                Description = entity.Description,
                Icon        = entity.Icon,
                Thumbnail   = entity.Thumbnail,
                NodeId      = entity.Id,
                AllowAtRoot = entity.AllowedAsRoot,
                IsContainer = entity.IsContainer,
                NodeDto     = BuildNodeDto(entity, nodeObjectType)
            };

            return(contentTypeDto);
        }
示例#8
0
 private static void MapContentTypeBase(IContentTypeBase contentTypeBase, ContentType type)
 {
     MapInfo(contentTypeBase, type.Info);
     MapStructure(contentTypeBase, type);
     MapGenericProperties(contentTypeBase, type);
     MapTabs(contentTypeBase, type);
 }
示例#9
0
        /// <summary>
        ///  So fiddling with the structure
        ///
        ///  In an umbraco export the structure can come out in a random order
        ///  for consistancy, and better tracking of changes we export the list
        ///  in alias order, that way it should always be the same every time
        ///  regardless of the creation order of the doctypes.
        ///
        ///  In earlier versions of umbraco, the structure export didn't always
        ///  work - so we redo the export, if it turns out this is fixed in 7.3
        ///  we shoud just do the xml sort like with properties, it will be faster
        /// </summary>
        internal XElement SerializeStructure(IContentTypeBase item)
        {
            var structureNode = new XElement("Structure");

            LogHelper.Debug <Events>("BASE: Content Types: {0}", () => item.AllowedContentTypes.Count());

            SortedList <string, Guid> allowedAliases = new SortedList <string, Guid>();

            foreach (var allowedType in item.AllowedContentTypes)
            {
                IContentTypeBase allowed = LookupById(allowedType.Id.Value);
                if (allowed != null)
                {
                    allowedAliases.Add(allowed.Alias, allowed.Key);
                }
            }


            foreach (var alias in allowedAliases)
            {
                structureNode.Add(new XElement(_itemType, alias.Key,
                                               new XAttribute("Key", alias.Value.ToString()))
                                  );
            }
            return(structureNode);
        }
        public static ContentType Map(IContentTypeBase umbracoContentType)
        {
            if (umbracoContentType is IMediaType)
                throw new NotImplementedException();

            return MapDocumentType(umbracoContentType);
        }
 private static void MapContentTypeBase(IContentTypeBase contentTypeBase, ContentType type)
 {
     MapInfo(contentTypeBase, type.Info);
     MapStructure(contentTypeBase, type);
     MapGenericProperties(contentTypeBase, type);
     MapTabs(contentTypeBase, type);
 }
示例#12
0
        protected void AssertContentType(IContentTypeBase umbType, ExpectedType type)
        {
            AssertBasicContentTypeInfo(umbType, type);
            var propGroups = umbType.PropertyGroups.Where(x => x.PropertyTypes.Count > 0);

            AssertTabs(type, propGroups);
            AssertProperties(umbType.PropertyTypes.Except(umbType.PropertyGroups.SelectMany(x => x.PropertyTypes), new CompareByProperty <PropertyType>(x => x.Alias)), type.Properties, type.Alias);
        }
示例#13
0
        /// <summary>
        /// Get all descendant content types
        /// </summary>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static IEnumerable <IContentTypeBase> Descendants(this IContentTypeBase contentType)
        {
            var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
            var descendants        = contentTypeService.GetContentTypeChildren(contentType.Id)
                                     .FlattenList(type => contentTypeService.GetContentTypeChildren(type.Id));

            return(descendants);
        }
示例#14
0
        /// <summary>
        /// This will remove all of the special membership provider properties which were required to display the property editors
        /// for editing - but the values have been mapped back to the MemberSave object directly - we don't want to keep these properties
        /// on the IMember because they will attempt to be persisted which we don't want since they might not even exist.
        /// </summary>
        /// <param name="contentType"></param>
        private void FilterMembershipProviderProperties(IContentTypeBase contentType)
        {
            var defaultProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
            //remove all membership properties, these values are set with the membership provider.
            var exclude = defaultProps.Select(x => x.Value.Alias).ToArray();

            FilterContentTypeProperties(contentType, exclude);
        }
示例#15
0
        public static ContentType Map(IContentTypeBase umbracoContentType)
        {
            if (umbracoContentType is IMediaType)
            {
                throw new NotImplementedException();
            }

            return(MapDocumentType(umbracoContentType));
        }
示例#16
0
    /// <summary>
    ///     This will remove all of the special membership provider properties which were required to display the property
    ///     editors
    ///     for editing - but the values have been mapped back to the MemberSave object directly - we don't want to keep these
    ///     properties
    ///     on the IMember because they will attempt to be persisted which we don't want since they might not even exist.
    /// </summary>
    /// <param name="contentType"></param>
    private void FilterMembershipProviderProperties(IContentTypeBase contentType)
    {
        Dictionary <string, PropertyType> defaultProps =
            ConventionsHelper.GetStandardPropertyTypeStubs(_shortStringHelper);
        //remove all membership properties, these values are set with the membership provider.
        var exclude = defaultProps.Select(x => x.Value.Alias).ToArray();

        FilterContentTypeProperties(contentType, exclude);
    }
示例#17
0
        protected ContentTypeBase(IContentTypeBase parent)
        {
            Mandate.ParameterNotNull(parent, "parent");

            _parentId            = new Lazy <int>(() => parent.Id);
            _allowedContentTypes = new List <ContentTypeSort>();
            _propertyGroups      = new PropertyGroupCollection();
            _propertyTypes       = new PropertyTypeCollection();
        }
        /// <summary>
        /// Creates a new property on the ContentType under the correct tab
        /// </summary>
        /// <param name="newContentType"></param>
        /// <param name="tabName"></param>
        /// <param name="dataTypeService"></param>
        /// <param name="atTabGeneric"></param>
        /// <param name="item"></param>
        public PropertyRegistration CreateProperty(IContentTypeBase newContentType, TabRegistration tab, PropertyInfo item, Type documentClrType)
        {
            ContentPropertyAttribute attribute = item.GetCodeFirstAttribute <ContentPropertyAttribute>();
            var tabPostfix = tab == null || !attribute.AddTabAliasToPropertyAlias ? null : tab.OriginalName == null ? tab.Name : tab.OriginalName;
            var dataType   = _dataTypeModule.GetDataType(item);
            var property   = new PropertyRegistration();

            property.Name              = attribute.Name;
            property.Alias             = tabPostfix == null ? attribute.Alias : StringHelperExtensions.HyphenToUnderscore(StringHelperExtensions.ParseUrl(attribute.Alias + "_" + tabPostfix, false));
            property.DataType          = dataType;
            property.PropertyAttribute = attribute;
            property.Metadata          = item;

            PropertyType propertyType = new PropertyType(dataType.Definition);

            propertyType.Name             = property.Name;
            propertyType.Alias            = property.Alias;
            propertyType.Description      = attribute.Description;
            propertyType.Mandatory        = attribute.Mandatory;
            propertyType.SortOrder        = attribute.SortOrder;
            propertyType.ValidationRegExp = attribute.ValidationRegularExpression;


            var propertyDeclaredOnThisDocType = property.Metadata.DeclaringType == documentClrType || property.Metadata.DeclaringType.GetCodeFirstAttribute <CodeFirstCommonBaseAttribute>(false) != null;
            var propertyDeclaredOnThisTab     = tab == null ? false : property.Metadata.DeclaringType == tab.ClrType;
            var tabDeclaredOnThisDocType      = tab == null ? false : tab.PropertyOfParent.DeclaringType == documentClrType || tab.PropertyOfParent.DeclaringType.GetCodeFirstAttribute <CodeFirstCommonBaseAttribute>() != null;
            var declaringTypeIsDocType        = property.Metadata.DeclaringType.GetCodeFirstAttribute <ContentTypeAttribute>(false) != null;
            var propertyIsFromCommonBase      = tab == null?
                                                property.Metadata.DeclaringType.GetCodeFirstAttribute <CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == documentClrType.BaseType
                                                :
                                                property.Metadata.DeclaringType.GetCodeFirstAttribute <CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == tab.ClrType.BaseType;

            if (tab == null)
            {
                if (propertyDeclaredOnThisDocType || propertyIsFromCommonBase)                               //only if property declared at this level (or inherited from a non-doctype class)
                {
                    if (!propertyIsFromCommonBase || !newContentType.PropertyTypeExists(propertyType.Alias)) //check if common base properties already exist
                    {
                        CodeFirstManager.Current.Log("Adding property " + property.Name + " on content type " + newContentType.Name, this);
                        newContentType.AddPropertyType(propertyType);
                    }
                }
            }
            else if (tabDeclaredOnThisDocType || propertyIsFromCommonBase)                                   //only if tab declared at this level
            {
                if (propertyDeclaredOnThisTab || propertyIsFromCommonBase)                                   //only if property declared at this level
                {
                    if (!propertyIsFromCommonBase || !newContentType.PropertyTypeExists(propertyType.Alias)) //check if common base properties already exist
                    {
                        CodeFirstManager.Current.Log("Adding property " + property.Name + " on tab " + tab.Name + " of content type " + newContentType.Name, this);
                        newContentType.AddPropertyType(propertyType, tab.Name);
                    }
                }
            }

            return(property);
        }
 private static void MapInfo(IContentTypeBase umbracoContentType, Info info)
 {
     info.Alias = umbracoContentType.Alias;
     info.AllowAtRoot = umbracoContentType.AllowedAsRoot;
     info.Description = umbracoContentType.Description;
     info.Icon = umbracoContentType.Icon;
     info.Name = umbracoContentType.Name;
     info.Thumbnail = umbracoContentType.Thumbnail;
 }
        private void MoveProperties(IContentTypeBase item, IDictionary <string, string> moves)
        {
            logger.Debug(serializerType, "MoveProperties");

            foreach (var move in moves)
            {
                item.MovePropertyType(move.Key, move.Value);
            }
        }
示例#21
0
 private static void MapInfo(IContentTypeBase umbracoContentType, Info info)
 {
     info.Alias       = umbracoContentType.Alias;
     info.AllowAtRoot = umbracoContentType.AllowedAsRoot;
     info.Description = umbracoContentType.Description;
     info.Icon        = umbracoContentType.Icon;
     info.Name        = umbracoContentType.Name;
     info.Thumbnail   = umbracoContentType.Thumbnail;
 }
示例#22
0
 public static IEnumerable <PropertyType> GetPreflightProperties(this IContentTypeBase type)
 {
     return(type.PropertyTypes
            .Where(p => p.PropertyEditorAlias == KnownPropertyAlias.Grid ||
                   p.PropertyEditorAlias == KnownPropertyAlias.NestedContent ||
                   p.PropertyEditorAlias == KnownPropertyAlias.Textbox ||
                   p.PropertyEditorAlias == KnownPropertyAlias.Textarea ||
                   p.PropertyEditorAlias == KnownPropertyAlias.Rte));
 }
示例#23
0
		protected ContentTypeBase(IContentTypeBase parent)
		{
			Mandate.ParameterNotNull(parent, "parent");

			_parentId = new Lazy<int>(() => parent.Id);
			_allowedContentTypes = new List<ContentTypeSort>();
			_propertyGroups = new PropertyGroupCollection();
            _propertyTypes = new PropertyTypeCollection();
		}
示例#24
0
 protected void AssertCompositions(IContentTypeBase umbType, ExpectedType type)
 {
     if (umbType is IContentTypeComposition)
     {
         AssertCompositions(umbType as IContentTypeComposition, type);
     }
     else if (type.CompositionAliases != null && type.CompositionAliases.Count() > 0)
     {
         throw new TestFailureException("Compositions expected for a type which is not IContentTypeComposition. Type: " + type.Name);
     }
 }
示例#25
0
        private static ContentType MapDocumentType(IContentTypeBase contentType)
        {
            var type = new DocumentType();
            var umbracoContentType = (IContentType)contentType;

            MapContentTypeBase(contentType, type);
            MapDocumentTypeInfo(umbracoContentType, type.Info);
            MapComposition(umbracoContentType, type);

            return(type);
        }
示例#26
0
 private void FilterContentTypeProperties(IContentTypeBase contentType, IEnumerable <string> exclude)
 {
     //remove all properties based on the exclusion list
     foreach (var remove in exclude)
     {
         if (contentType.PropertyTypeExists(remove))
         {
             contentType.RemovePropertyType(remove);
         }
     }
 }
 private void LogPropertySyncInfo(IContentTypeBase contentType, TabRegistration tab, PropertyRegistration property, string action, [CallerMemberName] string sourceMethod = null)
 {
     if (tab == null)
     {
         CodeFirstManager.Current.Log(string.Format("{0} property {1} on content type {2}", action, property.Name, contentType.Name), this, sourceMethod);
     }
     else
     {
         CodeFirstManager.Current.Log(string.Format("{0} property {1} on tab {2} of content type {3}", action, tab.Name, property.Name, contentType.Name), this, sourceMethod);
     }
 }
        /// <summary>
        /// Creates a new property on the ContentType under the correct tab
        /// </summary>
        /// <param name="newContentType"></param>
        /// <param name="tabName"></param>
        /// <param name="dataTypeService"></param>
        /// <param name="atTabGeneric"></param>
        /// <param name="item"></param>
        public PropertyRegistration CreateProperty(IContentTypeBase newContentType, TabRegistration tab, PropertyInfo item, Type documentClrType)
        {
            ContentPropertyAttribute attribute = item.GetCodeFirstAttribute<ContentPropertyAttribute>();
            var tabPostfix = tab == null || !attribute.AddTabAliasToPropertyAlias ? null : tab.OriginalName == null ? tab.Name : tab.OriginalName;
            var dataType = _dataTypeModule.GetDataType(item);
            var property = new PropertyRegistration();
            property.Name = attribute.Name;
            property.Alias = tabPostfix == null ? attribute.Alias : StringHelperExtensions.HyphenToUnderscore(StringHelperExtensions.ParseUrl(attribute.Alias + "_" + tabPostfix, false));
            property.DataType = dataType;
            property.PropertyAttribute = attribute;
            property.Metadata = item;

            PropertyType propertyType = new PropertyType(dataType.Definition);
            propertyType.Name = property.Name;
            propertyType.Alias = property.Alias;
            propertyType.Description = attribute.Description;
            propertyType.Mandatory = attribute.Mandatory;
            propertyType.SortOrder = attribute.SortOrder;
            propertyType.ValidationRegExp = attribute.ValidationRegularExpression;

            var propertyDeclaredOnThisDocType = property.Metadata.DeclaringType == documentClrType || property.Metadata.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>(false) != null;
            var propertyDeclaredOnThisTab = tab == null ? false : property.Metadata.DeclaringType == tab.ClrType;
            var tabDeclaredOnThisDocType = tab == null ? false : tab.PropertyOfParent.DeclaringType == documentClrType || tab.PropertyOfParent.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>() != null;
            var declaringTypeIsDocType = property.Metadata.DeclaringType.GetCodeFirstAttribute<ContentTypeAttribute>(false) != null;
            var propertyIsFromCommonBase = tab == null ?
                property.Metadata.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == documentClrType.BaseType
                :
                property.Metadata.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == tab.ClrType.BaseType;

            if (tab == null)
            {
                if (propertyDeclaredOnThisDocType || propertyIsFromCommonBase) //only if property declared at this level (or inherited from a non-doctype class)
                {
                    if (!propertyIsFromCommonBase || !newContentType.PropertyTypeExists(propertyType.Alias)) //check if common base properties already exist
                    {
                        CodeFirstManager.Current.Log("Adding property " + property.Name + " on content type " + newContentType.Name, this);
                        newContentType.AddPropertyType(propertyType);
                    }
                }
            }
            else if (tabDeclaredOnThisDocType || propertyIsFromCommonBase) //only if tab declared at this level
            {
                if (propertyDeclaredOnThisTab || propertyIsFromCommonBase) //only if property declared at this level
                {
                    if (!propertyIsFromCommonBase || !newContentType.PropertyTypeExists(propertyType.Alias)) //check if common base properties already exist
                    {
                        CodeFirstManager.Current.Log("Adding property " + property.Name + " on tab " + tab.Name + " of content type " + newContentType.Name, this);
                        newContentType.AddPropertyType(propertyType, tab.Name);
                    }
                }
            }

            return property;
        }
        private static ContentType MapDocumentType(IContentTypeBase contentType)
        {
            var type = new DocumentType();
            var umbracoContentType = (IContentType)contentType;

            MapContentTypeBase(contentType, type);
            MapDocumentTypeInfo(umbracoContentType, type.Info);
            MapComposition(umbracoContentType, type);
            
            return type;
        }
        private static void AddLabelProperty(IContentTypeBase mediaType, string name, string alias, DataTypeDatabaseType dataTypeDatabaseType)
        {
            var intranetUserIdPropertyType = GetLabelPropertyType(name, alias, dataTypeDatabaseType);

            if (mediaType.PropertyTypeExists(intranetUserIdPropertyType.Alias))
            {
                return;
            }

            mediaType.AddPropertyType(intranetUserIdPropertyType, AddVideoMediaTypeStepConstants.DocumentTypeTabNames.File);
        }
示例#31
0
        protected void DeserializeStructure(TObject item, XElement node)
        {
            logger.Debug <TObject>("Deserializing Structure");


            var structure = node.Element("Structure");

            if (structure == null)
            {
                return;
            }

            List <ContentTypeSort> allowed = new List <ContentTypeSort>();
            int sortOrder = 0;

            foreach (var baseNode in structure.Elements(ItemType))
            {
                logger.Debug <TObject>("baseNode {0}", baseNode.ToString());
                var alias = baseNode.Value;
                var key   = baseNode.Attribute("Key").ValueOrDefault(Guid.Empty);

                logger.Debug <TObject>("Structure: {0}", key);

                IContentTypeBase baseItem = default(IContentTypeBase);

                if (key != Guid.Empty)
                {
                    logger.Debug <TObject>("Structure By Key {0}", key);
                    // lookup by key (our prefered way)
                    baseItem = FindItem(key);
                }

                if (baseItem == null)
                {
                    logger.Debug <TObject>("Structure By Alias: {0}", alias);
                    // lookup by alias (less nice)
                    baseItem = FindItem(alias);
                }

                if (baseItem != null)
                {
                    logger.Debug <TObject>("Structure Found {0}", baseItem.Alias);

                    allowed.Add(new ContentTypeSort(
                                    new Lazy <int>(() => baseItem.Id), sortOrder, baseItem.Alias));

                    sortOrder++;
                }
            }

            logger.Debug <TObject>("Structure: {0} items", allowed.Count);
            item.AllowedContentTypes = allowed;
        }
示例#32
0
        protected ContentTypeBase(IContentTypeBase parent, string alias)
        {
            Mandate.ParameterNotNull(parent, "parent");

            _alias                            = alias;
            _parentId                         = new Lazy <int>(() => parent.Id);
            _allowedContentTypes              = new List <ContentTypeSort>();
            _propertyGroups                   = new PropertyGroupCollection();
            _propertyTypes                    = new PropertyTypeCollection();
            _propertyTypes.CollectionChanged += PropertyTypesChanged;
            _additionalData                   = new Dictionary <string, object>();
        }
示例#33
0
 protected void AssertBasicContentTypeInfo(IContentTypeBase umbType, ExpectedType type)
 {
     Assert(umbType, x => x.Name == type.Name, "Name doesn't match. Type: " + type.Name);
     Assert(umbType, x => x.SortOrder == type.SortOrder || type.SortOrder == 0, "Sort Order doesn't match. Type: " + type.Name);
     Assert(umbType, x => x.IsContainer == type.ListView, "ListView doesn't match. Type: " + type.Name);
     Assert(umbType, x => x.AllowedAsRoot == type.AllowAtRoot, "AllowAtRoot doesn't match. Type: " + type.Name);
     Assert(umbType, x => MatchOrBothEmpty(x.Description, type.Description), "Description doesn't match. Type: " + type.Name);
     Assert(umbType, x => x.Icon == type.IconWithColor, "Icon or colour doesn't match. Type: " + type.Name);
     AssertParent(umbType, type);
     AssertAllowedChildren(umbType, type);
     AssertCompositions(umbType, type);
 }
示例#34
0
        internal void DeserializeTabSortOrder(IContentTypeBase item, XElement node)
        {
            var tabNode = node.Element("Tabs");

            foreach (var tab in tabNode.Elements("Tab"))
            {
                var name      = tab.Element("Caption").Value;
                var sortOrder = tab.Element("SortOrder");

                if (sortOrder != null)
                {
                    if (!string.IsNullOrEmpty(sortOrder.Value))
                    {
                        var itemTab = item.PropertyGroups.FirstOrDefault(x => x.Name == name);
                        if (itemTab != null)
                        {
                            itemTab.SortOrder = int.Parse(sortOrder.Value);
                        }
                        else
                        {
                            LogHelper.Debug <Events>("Adding new Tab? {0}", () => name);
                            // at this point we might have a missing tab.
                            if (item.AddPropertyGroup(name))
                            {
                                itemTab = item.PropertyGroups.FirstOrDefault(x => x.Name == name);
                                if (itemTab != null)
                                {
                                    itemTab.SortOrder = int.Parse(sortOrder.Value);
                                }
                            }
                        }
                    }
                }
            }

            // remove tabs
            List <string> tabsToRemove = new List <string>();

            foreach (var tab in item.PropertyGroups)
            {
                if (tabNode.Elements("Tab").FirstOrDefault(x => x.Element("Caption").Value == tab.Name) == null)
                {
                    // no tab of this name in the import... remove it.
                    tabsToRemove.Add(tab.Name);
                }
            }

            foreach (var name in tabsToRemove)
            {
                item.PropertyGroups.Remove(name);
            }
        }
示例#35
0
        /// <summary>
        /// Ensure that all the built-in membership provider properties have their correct data type
        /// and property editors assigned. This occurs prior to saving so that the correct values are persisted.
        /// </summary>
        /// <param name="memberType"></param>
        private static void EnsureExplicitDataTypeForBuiltInProperties(IContentTypeBase memberType)
        {
            var builtinProperties = Constants.Conventions.Member.GetStandardPropertyTypeStubs();

            foreach (var propertyType in memberType.PropertyTypes)
            {
                if (builtinProperties.ContainsKey(propertyType.Alias))
                {
                    //this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line
                    propertyType.DataTypeId = 0;
                }
            }
        }
示例#36
0
        internal XElement SerializeTabs(IContentTypeBase item)
        {
            var tabs = new XElement("Tabs");

            foreach (var tab in item.PropertyGroups.OrderBy(x => x.SortOrder))
            {
                tabs.Add(new XElement("Tab",
                                      // new XElement("Key", tab.Key),
                                      new XElement("Caption", tab.Name),
                                      new XElement("SortOrder", tab.SortOrder)));
            }

            return(tabs);
        }
 private static void MapGenericProperties(IContentTypeBase contentTypeBase, ContentType type)
 {
     type.GenericProperties = contentTypeBase.PropertyGroups.SelectMany(pg =>
         pg.PropertyTypes.Select(p =>
             new GenericProperty
             {
                 Alias = p.Alias,
                 Description = p.Description,
                 Mandatory = p.Mandatory,
                 Name = p.Name,
                 Tab = pg.Name,
                 Type = p.PropertyEditorAlias,
                 Validation = p.ValidationRegExp
             }
             )
         ).ToList();
 }
        /// <summary>
        /// Scan the properties on tabs
        /// </summary>
        /// <param name="propertyTab"></param>
        /// <param name="contentType"></param>
        /// <param name="tabName"></param>
        /// <returns></returns>
        private IEnumerable<string> VerifyAllPropertiesOnTab(PropertyInfo propertyTab, IContentTypeBase contentType, TabRegistration registration, Type documentType, ref bool modified)
        {
            Type type = propertyTab.PropertyType;
            var properties = type.GetProperties().Where(x => x.GetCustomAttribute<ContentPropertyAttribute>() != null); //Do NOT initialise attribute here, causes initialisation exception
            var props = new List<PropertyRegistration>();
            registration._properties = props;
            registration.ClrType = type;

            if (properties.Count() > 0)
            {
                if (!contentType.PropertyGroups.Any(x => x.Name == registration.Name))
                {
                    contentType.AddPropertyGroup(registration.Name);
                }
                List<string> propertyAliases = new List<string>();
                foreach (var item in properties)
                {
                    CodeFirstManager.Current.Log("Syncing property " + item.Name + " on tab " + registration.Name + " of content type " + contentType.Name, this);
                    var propReg = _propertyModule.VerifyExistingProperty(contentType, registration, item, documentType, ref modified);
                    propertyAliases.Add(propReg.Alias);
                    props.Add(propReg);
                }
                return propertyAliases;
            }
            return new string[0];
        }
 private IContentTypeComposition Reparent(ContentTypeRegistration registration, IContentTypeComposition contentType, IContentTypeBase newParent, IContentTypeBase oldParent)
 {
     //TODO sort out reparenting
     throw new CodeFirstException("Changing parent types of existing content types is not supported. Consider dropping & recreating your content type hierarchy or using compositions instead." + Environment.NewLine +
         "Affected type alias: " + registration.Alias + ", previous parent alias: " + (oldParent == null ? "[none]" : oldParent.Alias) + ", new parent alias: " + (newParent == null ? "[none]" : newParent.Alias));
 }
        private void Prune(IContentTypeBase contentType, Type documentClrType, PropertyInfo[] tabProperties, IEnumerable<PropertyInfo> propertiesOfRoot)
        {
            bool modified = false;

            var propertiesToKeep = propertiesOfRoot.Where(x =>
            {
                var attr = x.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>(false);
                return x.DeclaringType == documentClrType || attr != null;
            }).Select(x => x.GetCodeFirstAttribute<ContentPropertyAttribute>().Alias)
            .Union(tabProperties.Where(x =>
            {
                var attr = x.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>(false);
                return x.DeclaringType == documentClrType || attr != null;
            }).SelectMany(x =>
            {
                return x.PropertyType.GetProperties().Where(y =>
                {
                    return (y.DeclaringType == x.PropertyType || y.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>(false) != null) && y.GetCodeFirstAttribute<ContentPropertyAttribute>() != null;
                }).Select(y =>
                    {
                      var attr = y.GetCodeFirstAttribute<ContentPropertyAttribute>();
                      var tabAttr = x.GetCodeFirstAttribute<ContentTabAttribute>();
                      return attr.AddTabAliasToPropertyAlias ? attr.Alias + "_" + tabAttr.Name.Replace(" ", "_") : attr.Alias;
                    });
            })).ToList();

            propertiesToKeep.AddRange(documentClrType.GetCustomAttributes<DoNotRemovePropertyAttribute>(true).Select(x => x.PropertyAlias));

            //loop through all the properties on the ContentType to see if they should be removed.
            var existingUmbracoProperties = contentType.PropertyTypes.ToArray();
            int length = contentType.PropertyTypes.Count();
            for (int i = 0; i < length; i++)
            {
                if (!propertiesToKeep.Any(x => x.Equals(existingUmbracoProperties[i].Alias, StringComparison.InvariantCultureIgnoreCase)))
                {
                    if (contentType.PropertyTypeExists(existingUmbracoProperties[i].Alias))
                    {
                        modified = true;
                        //remove the property
                        contentType.RemovePropertyType(existingUmbracoProperties[i].Alias);
                        var alias = existingUmbracoProperties[i].Alias;
                        var children = GetChildren(contentType);

                        //TODO is this needed? I reckon it shouldn't be
                        RemovePropertyFromChildren(alias, children);
                    }
                }
            }

            if (modified)
            {
                contentType.ResetDirtyProperties(false);
                Save(contentType);
            }
        }
        /// <summary>
        /// Loop through all properties and remove existing ones if necessary
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="type"></param>
        /// <param name="dataTypeService"></param>
        private void VerifyProperties(IContentTypeBase contentType, Type documentClrType, List<PropertyRegistration> propertyRegister, List<TabRegistration> tabRegister, ref bool modified)
        {
            var tabProperties = documentClrType.GetProperties().Where(x => x.GetCodeFirstAttribute<ContentTabAttribute>() != null).ToArray();
            var propertiesOfRoot = documentClrType.GetProperties().Where(x => x.GetCodeFirstAttribute<ContentPropertyAttribute>() != null);

            //Remove any properties which aren't in the CF definition
            Prune(contentType, documentClrType, tabProperties, propertiesOfRoot);

            foreach (var tabProperty in tabProperties)
            {
                var tabAttribute = tabProperty.GetCodeFirstAttribute<ContentTabAttribute>();
                var tabReg = new TabRegistration();
                tabReg.TabAttribute = tabAttribute;
                tabReg.Name = tabAttribute.Name;
                tabReg.OriginalName = tabAttribute.OriginalName;
                tabReg.PropertyOfParent = tabProperty;
                CodeFirstManager.Current.Log("Syncing tab " + tabReg.Name + " on content type " + contentType.Name, this);
                VerifyAllPropertiesOnTab(tabProperty, contentType, tabReg, documentClrType, ref modified);
                tabRegister.Add(tabReg);
            }

            foreach (var item in propertiesOfRoot)
            {
                CodeFirstManager.Current.Log("Syncing property " + item.Name + " on content type " + contentType.Name, this);
                var reg = _propertyModule.VerifyExistingProperty(contentType, null, item, documentClrType, ref modified);
                propertyRegister.Add(reg);
            }
        }
        /// <summary>
        /// Scans for properties on the model which have the UmbracoTab attribute
        /// </summary>
        /// <param name="newContentType"></param>
        /// <param name="model"></param>
        /// <param name="dataTypeService"></param>
        private void CreateTabs(IContentTypeBase newContentType, List<TabRegistration> tabRegister, Type contentClrType)
        {
            var properties = contentClrType.GetProperties().Where(x => x.GetCodeFirstAttribute<ContentTabAttribute>() != null).ToArray();
            int length = properties.Length;

            for (int i = 0; i < length; i++)
            {
                var tabAttribute = properties[i].GetCodeFirstAttribute<ContentTabAttribute>();
                var reg = new TabRegistration();
                var props = new List<PropertyRegistration>();
                reg._properties = props;
                reg.ClrType = properties[i].PropertyType;
                reg.Name = tabAttribute.Name;
                reg.OriginalName = tabAttribute.OriginalName;
                reg.TabAttribute = tabAttribute;
                reg.PropertyOfParent = properties[i];

                CodeFirstManager.Current.Log("Creating tab " + tabAttribute.Name + " on content type " + newContentType.Name, this);
                newContentType.AddPropertyGroup(tabAttribute.Name);
                newContentType.PropertyGroups.Where(x => x.Name == tabAttribute.Name).FirstOrDefault().SortOrder = tabAttribute.SortOrder;
                CreateProperties(properties[i], newContentType, reg, props, contentClrType);

                tabRegister.Add(reg);
            }
        }
 protected abstract void SaveContentType(IContentTypeBase contentType);
        /// <summary>
        /// Loop through all properties and remove existing ones if necessary
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="type"></param>
        /// <param name="dataTypeService"></param>
        private static void VerifyProperties(IContentTypeBase contentType, Type type, IDataTypeService dataTypeService)
        {
            var properties = type.GetProperties().Where(x => x.GetCustomAttribute<UmbracoTabAttribute>() != null).ToArray();
            List<string> propertiesThatShouldExist = new List<string>();

            foreach (var propertyTab in properties)
            {
                var tabAttribute = propertyTab.GetCustomAttribute<UmbracoTabAttribute>();
                if (!contentType.PropertyGroups.Any(x => x.Name == tabAttribute.Name))
                {
                    contentType.AddPropertyGroup(tabAttribute.Name);
                }

                propertiesThatShouldExist.AddRange(VerifyAllPropertiesOnTab(propertyTab, contentType, tabAttribute.Name, dataTypeService));
            }

            var propertiesOfRoot = type.GetProperties().Where(x => x.GetCustomAttribute<UmbracoPropertyAttribute>() != null);
            foreach (var item in propertiesOfRoot)
            {
                //TODO: check for correct name
                propertiesThatShouldExist.Add(VerifyExistingProperty(contentType, null, dataTypeService, item, true));
            }

            //loop through all the properties on the ContentType to see if they should be removed;
            var existingUmbracoProperties = contentType.PropertyTypes.ToArray();
            int length = contentType.PropertyTypes.Count();
            for (int i = 0; i < length; i++)
            {
                if (!propertiesThatShouldExist.Contains(existingUmbracoProperties[i].Alias))
                {
                    //remove the property
                    contentType.RemovePropertyType(existingUmbracoProperties[i].Alias);
                }
            }
        }
 private static ContentType MapContentTypeBase(IContentTypeBase contentTypeBase)
 {
     var type = new ContentType();
     MapContentTypeBase(contentTypeBase, type);
     return type;
 }
 protected void Delete(IContentTypeBase contentType)
 {
     if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Ensure)
     {
         throw new CodeFirstPassiveInitialisationException("The types defined in the database do not match the types passed in to initialise. In InitialisationMode.Ensure the types must match or the site will be prevented from starting.");
     }
     else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Sync)
     {
         DeleteContentType(contentType);
     }
     else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Passive)
     {
         return;
     }
     else
     {
         throw new CodeFirstException("Unknown initialisation mode");
     }
 }
 protected abstract void DeleteContentType(IContentTypeBase contentType);
		protected ContentTypeCompositionBase(IContentTypeBase parent) : base(parent)
		{
		}
 protected abstract IEnumerable<IContentTypeBase> GetChildren(IContentTypeBase contentType);
        private static string VerifyExistingProperty(IContentTypeBase contentType, string tabName, IDataTypeService dataTypeService, PropertyInfo item, bool atGenericTab = false)
        {
            UmbracoPropertyAttribute attribute = item.GetCustomAttribute<UmbracoPropertyAttribute>();
            IDataTypeDefinition dataTypeDef;
            if (string.IsNullOrEmpty(attribute.DataTypeInstanceName))
            {
                dataTypeDef = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias(attribute.DataType).FirstOrDefault();
            }
            else
            {
                dataTypeDef = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias(attribute.DataType).FirstOrDefault(x => x.Name == attribute.DataTypeInstanceName);
            }

            if (dataTypeDef != null)
            {
                PropertyType property;
                bool alreadyExisted = contentType.PropertyTypeExists(attribute.Alias);
                // TODO: Added attribute.Tab != null after Generic Properties add, is this bulletproof?
                if (alreadyExisted && attribute.Tab != null)
                {
                    property = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == attribute.Alias);
                }
                else
                {
                    property = new PropertyType(dataTypeDef);
                }

                property.Name = attribute.Name;
                //TODO: correct name?
                property.Alias = ((atGenericTab || !attribute.AddTabAliasToPropertyAlias) ? attribute.Alias : UmbracoCodeFirstExtensions.HyphenToUnderscore(UmbracoCodeFirstExtensions.ParseUrl(attribute.Alias + "_" + tabName, false)));
                property.Description = attribute.Description;
                property.Mandatory = attribute.Mandatory;

                if (!alreadyExisted)
                {
                    if (atGenericTab)
                    {
                        contentType.AddPropertyType(property);
                    }
                    else
                    {
                        contentType.AddPropertyType(property, tabName);
                    }
                }

                return property.Alias;
            }
            return null;
        }
        /// <summary>
        /// Creates a new property on the ContentType under the correct tab
        /// </summary>
        /// <param name="newContentType"></param>
        /// <param name="tabName"></param>
        /// <param name="dataTypeService"></param>
        /// <param name="atTabGeneric"></param>
        /// <param name="item"></param>
        private static void CreateProperty(IContentTypeBase newContentType, string tabName, IDataTypeService dataTypeService, bool atTabGeneric, PropertyInfo item)
        {
            UmbracoPropertyAttribute attribute = item.GetCustomAttribute<UmbracoPropertyAttribute>();

            IDataTypeDefinition dataTypeDef;
            if (string.IsNullOrEmpty(attribute.DataTypeInstanceName))
            {
                dataTypeDef = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias(attribute.DataType).FirstOrDefault();
            }
            else
            {
                dataTypeDef = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias(attribute.DataType).FirstOrDefault(x => x.Name == attribute.DataTypeInstanceName);
            }

            if (dataTypeDef != null)
            {
                PropertyType propertyType = new PropertyType(dataTypeDef);
                propertyType.Name = attribute.Name;
                propertyType.Alias = ((atTabGeneric || !attribute.AddTabAliasToPropertyAlias) ? attribute.Alias : UmbracoCodeFirstExtensions.HyphenToUnderscore(UmbracoCodeFirstExtensions.ParseUrl(attribute.Alias + "_" + tabName, false)));
                propertyType.Description = attribute.Description;
                propertyType.Mandatory = attribute.Mandatory;
                propertyType.SortOrder = attribute.SortOrder;
                propertyType.ValidationRegExp = attribute.ValidationRegularExpression;

                if (atTabGeneric)
                {
                    newContentType.AddPropertyType(propertyType);
                }
                else
                {
                    newContentType.AddPropertyType(propertyType, tabName);
                }
            }
        }
 protected void Save(IContentTypeBase contentType)
 {
     CodeFirstManager.Current.Log("Attempting to save changes to content type " + contentType.Name, this);
     if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Ensure)
     {
         CodeFirstManager.Current.Log("ERROR: In Ensure mode and the following content type is not sync'ed: " + contentType.Name, this);
         throw new CodeFirstPassiveInitialisationException("The types defined in the database do not match the types passed in to initialise. In InitialisationMode.Ensure the types must match or the site will be prevented from starting.");
     }
     else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Sync)
     {
         SaveContentType(contentType);
         CodeFirstManager.Current.Log("Saved changes to content type " + contentType.Name, this);
     }
     else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Passive)
     {
         CodeFirstManager.Current.Log("In passive mode - ignoring changes to content type " + contentType.Name, this);
         return;
     }
     else
     {
         throw new CodeFirstException("Unknown initialisation mode");
     }
 }
 /// <summary>
 /// Scan the properties on tabs
 /// </summary>
 /// <param name="propertyTab"></param>
 /// <param name="contentType"></param>
 /// <param name="tabName"></param>
 /// <param name="dataTypeService"></param>
 /// <returns></returns>
 private static IEnumerable<string> VerifyAllPropertiesOnTab(PropertyInfo propertyTab, IContentTypeBase contentType, string tabName, IDataTypeService dataTypeService)
 {
     Type type = propertyTab.PropertyType;
     var properties = type.GetProperties().Where(x => x.GetCustomAttribute<UmbracoPropertyAttribute>() != null);
     if (properties.Count() > 0)
     {
         List<string> propertyAliases = new List<string>();
         foreach (var item in properties)
         {
             propertyAliases.Add(VerifyExistingProperty(contentType, tabName, dataTypeService, item));
         }
         return propertyAliases;
     }
     return new string[0];
 }
        /// <summary>
        /// Checks whether a property exists and adds if if it does not. The data type, alias, description and mandatory flag are update for existing properties, but not persisted.
        /// Callers should persist the value.
        /// </summary>
        public PropertyRegistration VerifyExistingProperty(IContentTypeBase contentType, TabRegistration tab, PropertyInfo item, Type documentClrType, ref bool modified)
        {
            ContentPropertyAttribute attribute = item.GetCodeFirstAttribute<ContentPropertyAttribute>();
            var tabPostfix = tab == null || !attribute.AddTabAliasToPropertyAlias ? null : tab.OriginalName == null ? tab.Name : tab.OriginalName;
            var property = new PropertyRegistration();
            var alias = property.Alias = tabPostfix == null ? attribute.Alias : StringHelperExtensions.HyphenToUnderscore(StringHelperExtensions.ParseUrl(attribute.Alias + "_" + tabPostfix, false));
            var dataType = property.DataType = _dataTypeModule.GetDataType(item);
            property.Name = attribute.Name;
            property.PropertyAttribute = attribute;
            property.Metadata = item;

            LogPropertySyncInfo(contentType, tab, property, "Syncing");

            bool alreadyExisted = contentType.PropertyTypeExists(alias);
            PropertyType umbracoProperty = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == alias);

            if (umbracoProperty == null && alreadyExisted)
            {
                //This is a property from an underlying tab. Leave it alone. Log a warning in case this is an orphaned property.
                LogPropertySyncInfo(contentType, tab, property, "Ignoring inherited");
                return property;
            }

            if(alreadyExisted)
            {
                modified = modified ||
                               !umbracoProperty.Name.Equals(attribute.Name, StringComparison.InvariantCultureIgnoreCase) ||
                               umbracoProperty.Mandatory != attribute.Mandatory ||
                               (umbracoProperty.SortOrder != attribute.SortOrder && attribute.SortOrder != 0); //don't count sort order changes if no sort order is specified, as Umbraco will have assigned an automatic one

                if (umbracoProperty.ValidationRegExp != attribute.ValidationRegularExpression)
                {
                    //If not both null/empty
                    if (!(string.IsNullOrEmpty(umbracoProperty.ValidationRegExp) && string.IsNullOrEmpty(attribute.ValidationRegularExpression)))
                    {
                        modified = true;
                        LogPropertySyncInfo(contentType, tab, property, "ValidationRegExp changed on");
                    }
                }

                if (umbracoProperty.Description != attribute.Description)
                {
                    //If not both null/empty
                    if (!(string.IsNullOrEmpty(umbracoProperty.Description) && string.IsNullOrEmpty(attribute.Description)))
                    {
                        modified = true;
                        LogPropertySyncInfo(contentType, tab, property, "Description changed on");
                    }
                }

                if (modified)
                {
                    if (!umbracoProperty.Name.Equals(attribute.Name, StringComparison.InvariantCultureIgnoreCase))
                        LogPropertySyncInfo(contentType, tab, property, "Name changed on");

                    if (umbracoProperty.Mandatory != attribute.Mandatory)
                        LogPropertySyncInfo(contentType, tab, property, "Mandatory changed on");

                    if ((umbracoProperty.SortOrder != attribute.SortOrder && attribute.SortOrder != 0))
                        LogPropertySyncInfo(contentType, tab, property, "SortOrder changed on");
                }
            }

            if (umbracoProperty == null)
            {
                try
                {
                    modified = true;
                    umbracoProperty = new PropertyType(dataType.Definition);
                    LogPropertySyncInfo(contentType, tab, property, "Creating new");
                }
                catch (Exception ex)
                {

                }
            }
            else if (umbracoProperty.DataTypeDefinitionId != dataType.Definition.Id)
            {
                modified = true;
                umbracoProperty.DataTypeDefinitionId = dataType.Definition.Id;
                LogPropertySyncInfo(contentType, tab, property, "Data type changed for");
            }

            umbracoProperty.Name = attribute.Name;
            umbracoProperty.Alias = alias;
            umbracoProperty.Description = attribute.Description;
            umbracoProperty.Mandatory = attribute.Mandatory;
            umbracoProperty.SortOrder = attribute.SortOrder;
            umbracoProperty.ValidationRegExp = attribute.ValidationRegularExpression;

            var propertyDeclaredOnThisDocType = property.Metadata.DeclaringType == documentClrType;
            var propertyDeclaredOnThisTab = tab == null ? false : property.Metadata.DeclaringType == tab.ClrType;
            var tabDeclaredOnThisDocType = tab == null ? false : tab.PropertyOfParent.DeclaringType == documentClrType || tab.PropertyOfParent.DeclaringType.GetCustomAttribute<ContentTypeAttribute>() == null;
            var declaringTypeIsDocType = property.Metadata.DeclaringType.GetCodeFirstAttribute<ContentTypeAttribute>(false) != null;
            var propertyIsFromCommonBase = tab == null ?
                property.Metadata.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == documentClrType.BaseType
                :
                property.Metadata.DeclaringType.GetCodeFirstAttribute<CodeFirstCommonBaseAttribute>() != null && property.Metadata.DeclaringType == tab.ClrType.BaseType;

            if (alreadyExisted)
            {
                if (propertyIsFromCommonBase || (tabDeclaredOnThisDocType && propertyDeclaredOnThisTab))
                {
                    var currentTab = contentType.PropertyGroups.Where(x => x.PropertyTypes.Any(y => y.Alias == alias)).FirstOrDefault();
                    if (currentTab == null || !currentTab.Name.Equals(tab.Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        modified = true;
                        contentType.MovePropertyType(alias, tab.Name);
                        LogPropertySyncInfo(contentType, tab, property, string.Format("Moved from tab {0}:", tab.Name));
                    }
                }
            }
            else
            {
                if (tab == null)
                {
                    if (propertyDeclaredOnThisDocType || !declaringTypeIsDocType) //only if property declared at this level (or inherited from common base)
                    {
                        if (!propertyIsFromCommonBase || !contentType.PropertyTypeExists(umbracoProperty.Alias)) //check if common base properties already exist
                        {
                            LogPropertySyncInfo(contentType, tab, property, "Adding");
                            contentType.AddPropertyType(umbracoProperty);
                        }
                    }
                }
                else if (tabDeclaredOnThisDocType || propertyIsFromCommonBase) //only if tab declared at this level
                {
                    if (propertyDeclaredOnThisTab || propertyIsFromCommonBase) //only if property declared at this level
                    {
                        if (!propertyIsFromCommonBase || (tabDeclaredOnThisDocType && !contentType.PropertyTypeExists(umbracoProperty.Alias))) //check if common base properties already exist
                        {
                            LogPropertySyncInfo(contentType, tab, property, "Adding");
                            contentType.AddPropertyType(umbracoProperty, tab.Name);
                        }
                    }
                }
            }

            return property;
        }
 private static void MapStructure(IContentTypeBase contentTypeBase, ContentType type)
 {
     type.Structure = contentTypeBase.AllowedContentTypes.Select(ct => ct.Alias).ToList();
 }
 private void LogPropertySyncInfo(IContentTypeBase contentType, TabRegistration tab, PropertyRegistration property, string action, [CallerMemberName]string sourceMethod = null)
 {
     if (tab == null)
     {
         CodeFirstManager.Current.Log(string.Format("{0} property {1} on content type {2}", action, property.Name, contentType.Name), this, sourceMethod);
     }
     else
     {
         CodeFirstManager.Current.Log(string.Format("{0} property {1} on tab {2} of content type {3}", action, tab.Name, property.Name, contentType.Name), this, sourceMethod);
     }
 }
 private static void MapTabs(IContentTypeBase contentTypeBase, ContentType type)
 {
     type.Tabs = contentTypeBase.PropertyGroups.Select(pg => new Tab {Caption = pg.Name}).ToList();
 }
 /// <summary>
 /// Every property on the Tab object is scanned for the UmbracoProperty attribute
 /// </summary>
 /// <param name="propertyInfo"></param>
 /// <param name="newContentType"></param>
 /// <param name="tabName"></param>
 /// <param name="dataTypeService"></param>
 /// <param name="atTabGeneric"></param>
 private void CreateProperties(PropertyInfo propertyInfo, IContentTypeBase newContentType, TabRegistration tab, List<PropertyRegistration> propertyRegister, Type documentClrType)
 {
     Type type = propertyInfo.PropertyType;
     var properties = type.GetProperties().Where(x => x.GetCustomAttribute<ContentPropertyAttribute>() != null); //Do NOT initialise attributes here, causes exception
     if (properties.Count() > 0)
     {
         foreach (var item in properties)
         {
             var reg = _propertyModule.CreateProperty(newContentType, tab, item, documentClrType);
             propertyRegister.Add(reg);
         }
     }
 }
 protected abstract IContentTypeComposition CreateContentType(IContentTypeBase parent);
        private static IList<TypeModel> GetTypes(PublishedItemType itemType, IContentTypeBase[] contentTypes)
        {
            var typeModels = new List<TypeModel>();

            // get the types and the properties
            foreach (var contentType in contentTypes)
            {
                var typeModel = new TypeModel
                {
                    Id = contentType.Id,
                    Alias = contentType.Alias,
                    ClrName = contentType.Alias.ToCleanString(CleanStringType.ConvertCase | CleanStringType.PascalCase),
                    ParentId = contentType.ParentId,

                    Name = contentType.Name,
                    Description = contentType.Description
                };

                switch (itemType)
                {
                    case PublishedItemType.Content:
                        typeModel.ItemType = TypeModel.ItemTypes.Content;
                        break;
                    case PublishedItemType.Media:
                        typeModel.ItemType = TypeModel.ItemTypes.Media;
                        break;
                    case PublishedItemType.Member:
                        typeModel.ItemType = TypeModel.ItemTypes.Member;
                        break;
                    default:
                        throw new InvalidOperationException(string.Format("Unsupported PublishedItemType \"{0}\".", itemType));
                }

                typeModels.Add(typeModel);

                var publishedContentType = PublishedContentType.Get(itemType, contentType.Alias);

                foreach (var propertyType in contentType.PropertyTypes)
                {
                    var propertyModel = new PropertyModel
                    {
                        Alias = propertyType.Alias,
                        ClrName = propertyType.Alias.ToCleanString(CleanStringType.ConvertCase | CleanStringType.PascalCase),

                        Name = propertyType.Name,
                        Description = propertyType.Description
                    };

                    var publishedPropertyType = publishedContentType.GetPropertyType(propertyType.Alias);
                    propertyModel.ClrType = publishedPropertyType.ClrType;

                    typeModel.Properties.Add(propertyModel);
                }
            }

            // wire the base types
            foreach (var typeModel in typeModels.Where(x => x.ParentId > 0))
            {
                typeModel.BaseType = typeModels.SingleOrDefault(x => x.Id == typeModel.ParentId);
                // Umbraco 7.4 introduces content types containers, so even though ParentId > 0, the parent might
                // not be a content type - here we assume that BaseType being null while ParentId > 0 means that 
                // the parent is a container (and we don't check).
                typeModel.IsParent = typeModel.BaseType != null;
            }

            // discover mixins
            foreach (var contentType in contentTypes)
            {
                var typeModel = typeModels.SingleOrDefault(x => x.Id == contentType.Id);
                if (typeModel == null) throw new Exception("Panic: no type model matching content type.");

                IEnumerable<IContentTypeComposition> compositionTypes;
                var contentTypeAsMedia = contentType as IMediaType;
                var contentTypeAsContent = contentType as IContentType;
                var contentTypeAsMember = contentType as IMemberType;
                if (contentTypeAsMedia != null) compositionTypes = contentTypeAsMedia.ContentTypeComposition;
                else if (contentTypeAsContent != null) compositionTypes = contentTypeAsContent.ContentTypeComposition;
                else if (contentTypeAsMember != null) compositionTypes = contentTypeAsMember.ContentTypeComposition;
                else throw new Exception(string.Format("Panic: unsupported type \"{0}\".", contentType.GetType().FullName));

                foreach (var compositionType in compositionTypes)
                {
                    var compositionModel = typeModels.SingleOrDefault(x => x.Id == compositionType.Id);
                    if (compositionModel == null) throw new Exception("Panic: composition type does not exist.");

                    if (compositionType.Id == contentType.ParentId) continue;

                    // add to mixins
                    typeModel.MixinTypes.Add(compositionModel);

                    // mark as mixin - as well as parents
                    compositionModel.IsMixin = true;
                    while ((compositionModel = compositionModel.BaseType) != null)
                        compositionModel.IsMixin = true;
                }
            }

            return typeModels;
        }