Helper class for saving information about each property and attribute of an entity Note: the type of a field or attribute does not neccesarily determine the ui rendered for filtering. For example, a Single-Select attribute will use a multi-select ui so that user can filter on one or more values. The FilterFieldType property determines the UI rendered for filtering and not the type of field. Entity Property Types and their renderd filter field type string -> TEXT bool or bool? -> SINGLE_SELECT date or date? -> DATE int or int? Defined Values -> MULTI_SELECT otherwise -> INTEGER enumeration -> MULTI_SELECT Attribute types and their rendered filter field type MULTI_SELECT -> MULTI_SELECT SINGLE_SELECT -> MULTI_SELECT BOOLEAN -> SINGLE_SELECT (True or False) DATE -> DATE INTEGER -> INTEGER TEXT -> TEXT
Example #1
0
        /// <summary>
        /// Sets the entity field from field type attribute.
        /// </summary>
        /// <param name="entityField">The entity field.</param>
        /// <param name="fieldTypeAttribute">The field type attribute.</param>
        /// <returns></returns>
        private static bool SetEntityFieldFromFieldTypeAttribute(EntityField entityField, FieldTypeAttribute fieldTypeAttribute)
        {
            if (fieldTypeAttribute != null)
            {
                var fieldTypeCache = FieldTypeCache.Get(fieldTypeAttribute.FieldTypeGuid);
                if (fieldTypeCache != null && fieldTypeCache.Field != null)
                {
                    if (fieldTypeCache.Field.HasFilterControl())
                    {
                        if (entityField.Title.EndsWith(" Id"))
                        {
                            entityField.Title = entityField.Title.ReplaceLastOccurrence(" Id", string.Empty);
                        }

                        entityField.FieldType = fieldTypeCache;
                        if (fieldTypeAttribute.ConfigurationKey != null && fieldTypeAttribute.ConfigurationValue != null)
                        {
                            entityField.FieldConfig.Add(fieldTypeAttribute.ConfigurationKey, new ConfigurationValue(fieldTypeAttribute.ConfigurationValue));
                        }

                        return(true);
                    }
                }
            }

            return(false);
        }
Example #2
0
        /// <summary>
        /// Create an EntityField for an Attribute.
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        /// <param name="limitToFilterableAttributes"></param>
        public static EntityField GetEntityFieldForAttribute(AttributeCache attribute, bool limitToFilterableAttributes = true)
        {
            // Ensure field name only has Alpha, Numeric and underscore chars
            string fieldName = attribute.Key.RemoveSpecialCharacters().Replace(".", "");

            EntityField entityField = null;

            // Make sure that the attributes field type actually renders a filter control if limitToFilterableAttributes
            var fieldType = FieldTypeCache.Read(attribute.FieldTypeId);

            if (fieldType != null && (!limitToFilterableAttributes || fieldType.Field.HasFilterControl()))
            {
                entityField       = new EntityField(fieldName, FieldKind.Attribute, typeof(string), attribute.Guid, fieldType);
                entityField.Title = attribute.Name.SplitCase();
                entityField.TitleWithoutQualifier = entityField.Title;

                foreach (var config in attribute.QualifierValues)
                {
                    entityField.FieldConfig.Add(config.Key, config.Value);
                }

                // Special processing for Entity Type "Group" to handle sub-types that are distinguished by GroupTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Group)) && attribute.EntityTypeQualifierColumn == "GroupTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var groupType = new GroupTypeService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (groupType != null)
                        {
                            // Append the Qualifier to the title
                            entityField.Title = string.Format("{0} ({1})", attribute.Name, groupType.Name);
                        }
                    }
                }

                // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ContentChannelItem)) && attribute.EntityTypeQualifierColumn == "ContentChannelTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var contentChannelType = new ContentChannelTypeService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (contentChannelType != null)
                        {
                            // Append the Qualifier to the title
                            entityField.Title = string.Format("{0} ({1})", attribute.Name, contentChannelType.Name);
                        }
                    }
                }
            }
            return(entityField);
        }
Example #3
0
        /// <summary>
        /// Adds the entity field for attribute.
        /// </summary>
        /// <param name="entityFields">The entity fields.</param>
        /// <param name="attribute">The attribute.</param>
        public static void AddEntityFieldForAttribute(List <EntityField> entityFields, AttributeCache attribute)
        {
            // Ensure prop name is unique
            string propName = attribute.Key;
            int    i        = 1;

            while (entityFields.Any(p => p.Name.Equals(propName, StringComparison.CurrentCultureIgnoreCase)))
            {
                propName = attribute.Key + (i++).ToString();
            }

            // Make sure that the attributes field type actually renders a filter control
            var fieldType = FieldTypeCache.Read(attribute.FieldTypeId);

            if (fieldType != null && fieldType.Field.FilterControl(attribute.QualifierValues, propName, true) != null)
            {
                var entityField = new EntityField();
                entityField.Name          = propName;
                entityField.Title         = attribute.Name.SplitCase();
                entityField.FieldKind     = FieldKind.Attribute;
                entityField.PropertyType  = typeof(string);
                entityField.AttributeGuid = attribute.Guid;
                entityField.FieldType     = fieldType;
                foreach (var config in attribute.QualifierValues)
                {
                    entityField.FieldConfig.Add(config.Key, config.Value);
                }

                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Group)) && attribute.EntityTypeQualifierColumn == "GroupTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var groupType = new GroupTypeService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (groupType != null)
                        {
                            entityField.Title = string.Format("{0} ({1})", attribute.Name, groupType.Name);
                        }
                    }
                }

                entityFields.Add(entityField);
            }
        }
Example #4
0
        /// <summary>
        /// Create an EntityField for an Attribute.
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        public static EntityField GetEntityFieldForAttribute(AttributeCache attribute)
        {
            string fieldName = attribute.Key;

            EntityField entityField = null;

            // Make sure that the attributes field type actually renders a filter control
            var fieldType = FieldTypeCache.Read(attribute.FieldTypeId);

            if (fieldType != null && fieldType.Field.FilterControl(attribute.QualifierValues, fieldName, true) != null)
            {
                entityField               = new EntityField();
                entityField.Name          = fieldName;
                entityField.Title         = attribute.Name.SplitCase();
                entityField.FieldKind     = FieldKind.Attribute;
                entityField.PropertyType  = typeof(string);
                entityField.AttributeGuid = attribute.Guid;
                entityField.FieldType     = fieldType;
                foreach (var config in attribute.QualifierValues)
                {
                    entityField.FieldConfig.Add(config.Key, config.Value);
                }

                // Special processing for Entity Type "Group" to handle sub-types that are distinguished by GroupTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Group)) && attribute.EntityTypeQualifierColumn == "GroupTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var groupType = new GroupTypeService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (groupType != null)
                        {
                            entityField.Title = string.Format("{0} ({1})", attribute.Name, groupType.Name);
                        }
                    }
                }
            }

            return(entityField);
        }
Example #5
0
        /// <summary>
        /// Create an EntityField for an Attribute.
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        /// <param name="limitToFilterableAttributes"></param>
        public static EntityField GetEntityFieldForAttribute(AttributeCache attribute, bool limitToFilterableAttributes = true)
        {
            // Ensure field name only has Alpha, Numeric and underscore chars
            string fieldName = attribute.Key.RemoveSpecialCharacters().Replace(".", "");

            EntityField entityField = null;

            // Make sure that the attributes field type actually renders a filter control if limitToFilterableAttributes
            var fieldType = FieldTypeCache.Read(attribute.FieldTypeId);

            if (fieldType != null && (!limitToFilterableAttributes || fieldType.Field.HasFilterControl()))
            {
                entityField       = new EntityField(fieldName, FieldKind.Attribute, typeof(string), attribute.Guid, fieldType);
                entityField.Title = attribute.Name.SplitCase();
                entityField.TitleWithoutQualifier = entityField.Title;

                foreach (var config in attribute.QualifierValues)
                {
                    entityField.FieldConfig.Add(config.Key, config.Value);
                }

                // Special processing for Entity Type "Group" to handle sub-types that are distinguished by GroupTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Group)) && attribute.EntityTypeQualifierColumn == "GroupTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var groupType = GroupTypeCache.Read(attribute.EntityTypeQualifierValue.AsInteger(), rockContext);
                        if (groupType != null)
                        {
                            // Append the Qualifier to the title
                            entityField.AttributeEntityTypeQualifierName = groupType.Name;
                            entityField.Title = string.Format("{0} ({1})", attribute.Name, groupType.Name);
                        }
                    }
                }

                // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ContentChannelItem)) && attribute.EntityTypeQualifierColumn == "ContentChannelTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var contentChannelType = new ContentChannelTypeService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (contentChannelType != null)
                        {
                            // Append the Qualifier to the title
                            entityField.AttributeEntityTypeQualifierName = contentChannelType.Name;
                            entityField.Title = string.Format("{0} (ChannelType: {1})", attribute.Name, contentChannelType.Name);
                        }
                    }
                }

                // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ContentChannelItem)) && attribute.EntityTypeQualifierColumn == "ContentChannelId")
                {
                    using (var rockContext = new RockContext())
                    {
                        var contentChannel = new ContentChannelService(rockContext).Get(attribute.EntityTypeQualifierValue.AsInteger());
                        if (contentChannel != null)
                        {
                            // Append the Qualifier to the title
                            entityField.AttributeEntityTypeQualifierName = contentChannel.Name;
                            entityField.Title = string.Format("{0} (Channel: {1})", attribute.Name, contentChannel.Name);
                        }
                    }
                }

                // Special processing for Entity Type "Workflow" to handle sub-types that are distinguished by WorkflowTypeId.
                if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Rock.Model.Workflow)) && attribute.EntityTypeQualifierColumn == "WorkflowTypeId")
                {
                    using (var rockContext = new RockContext())
                    {
                        int workflowTypeId = attribute.EntityTypeQualifierValue.AsInteger();
                        if (_workflowTypeNameLookup == null)
                        {
                            _workflowTypeNameLookup = new WorkflowTypeService(rockContext).Queryable().ToDictionary(k => k.Id, v => v.Name);
                        }

                        var workflowTypeName = _workflowTypeNameLookup.ContainsKey(workflowTypeId) ? _workflowTypeNameLookup[workflowTypeId] : null;
                        if (workflowTypeName != null)
                        {
                            // Append the Qualifier to the title for Workflow Attributes
                            entityField.AttributeEntityTypeQualifierName = workflowTypeName;
                            entityField.Title = string.Format("({1}) {0} ", attribute.Name, workflowTypeName);
                        }
                    }
                }
            }

            return(entityField);
        }
Example #6
0
        /// <summary>
        /// Builds an expression for an attribute field
        /// </summary>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="entityField">The property.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static Expression GetAttributeExpression( IService serviceInstance, ParameterExpression parameterExpression, EntityField entityField, List<string> values )
        {
            var service = new AttributeValueService( (RockContext)serviceInstance.Context );

            var attributeValues = service.Queryable().Where( v =>
                v.EntityId.HasValue &&
                v.Value != string.Empty );

            if ( entityField.AttributeGuid.HasValue )
            {
                attributeValues = attributeValues.Where( v => v.Attribute.Guid == entityField.AttributeGuid );
            }
            else
            {
                attributeValues = attributeValues.Where( v => v.Attribute.Key == entityField.Name && v.Attribute.FieldTypeId == entityField.FieldType.Id );
            }

            ParameterExpression attributeValueParameterExpression = Expression.Parameter( typeof( AttributeValue ), "v" );

            // Determine the appropriate comparison type to use for this Expression.
            // Attribute Value records only exist for Entities that have a value specified for the Attribute.
            // Therefore, if the specified comparison works by excluding certain values we must invert our filter logic:
            // first we find the Attribute Values that match those values and then we exclude the associated Entities from the result set.
            var comparisonType = ComparisonType.EqualTo;
            ComparisonType evaluatedComparisonType = comparisonType;

            if ( values.Count >= 2 )
            {
                string comparisonValue = values[0];
                if ( comparisonValue != "0" )
                {
                    comparisonType = comparisonValue.ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );
                }

                switch ( comparisonType )
                {
                    case ComparisonType.DoesNotContain:
                        evaluatedComparisonType = ComparisonType.Contains;
                        break;
                    case ComparisonType.IsBlank:
                        evaluatedComparisonType = ComparisonType.IsNotBlank;
                        break;
                    case ComparisonType.LessThan:
                        evaluatedComparisonType = ComparisonType.GreaterThanOrEqualTo;
                        break;
                    case ComparisonType.LessThanOrEqualTo:
                        evaluatedComparisonType = ComparisonType.GreaterThan;
                        break;
                    case ComparisonType.NotEqualTo:
                        evaluatedComparisonType = ComparisonType.EqualTo;
                        break;
                    default:
                        evaluatedComparisonType = comparisonType;
                        break;
                }

                values[0] = evaluatedComparisonType.ToString();
            }

            var filterExpression = entityField.FieldType.Field.AttributeFilterExpression( entityField.FieldConfig, values, attributeValueParameterExpression );
            if ( filterExpression != null )
            {
                attributeValues = attributeValues.Where( attributeValueParameterExpression, filterExpression, null );
            }

            IQueryable<int> ids = attributeValues.Select( v => v.EntityId.Value );

            MemberExpression propertyExpression = Expression.Property( parameterExpression, "Id" );
            ConstantExpression idsExpression = Expression.Constant( ids.AsQueryable(), typeof( IQueryable<int> ) );
            Expression expression = Expression.Call( typeof( Queryable ), "Contains", new Type[] { typeof( int ) }, idsExpression, propertyExpression );

            // If we have used an inverted comparison type for the evaluation, invert the Expression so that it excludes the matching Entities.
            if ( comparisonType != evaluatedComparisonType )
            {
                return Expression.Not( expression );
            }
            else
            {
                return expression;
            }
        }
Example #7
0
        /// <summary>
        /// Gets the entity fields for a specific Entity
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <param name="limitToFilterableFields">if set to <c>true</c> [limit to filterable fields].</param>
        /// <returns></returns>
        private static List <EntityField> GetEntityFields(Type entityType, IEntity entity, bool includeOnlyReportingFields = true, bool limitToFilterableFields = true)
        {
            List <EntityField> entityFields = null;

            if (HttpContext.Current != null)
            {
                entityFields = HttpContext.Current.Items[EntityHelper.GetCacheKey(entityType, entity, includeOnlyReportingFields, limitToFilterableFields)] as List <EntityField>;
                if (entityFields != null)
                {
                    return(entityFields);
                }
            }

            if (entityFields == null)
            {
                entityFields = new List <EntityField>();
            }

            List <PropertyInfo> entityProperties = entityType.GetProperties().ToList();

            // filter the properties to narrow down the ones that we want to include in EntityFields
            var filteredEntityProperties = entityProperties
                                           .Where((p) =>
            {
                var includeForReportingAttribute = p.GetCustomAttribute <IncludeForReportingAttribute>() != null;

                // if the property has an IncludeForReportingAttribute, include it regardless
                if (includeForReportingAttribute)
                {
                    return(true);
                }

                // if marked as NotMapped, don't include it since it won't work in a LinqToEntity expression
                var notMapped = p.GetCustomAttribute <NotMappedAttribute>() != null;

                bool hideFromReporting = false;
                if (includeOnlyReportingFields)
                {
                    hideFromReporting = p.GetCustomAttribute <HideFromReportingAttribute>() != null;
                }

                // if the property has NotMappedAttribute or should be hidden from reporting, don't show it
                if (notMapped || hideFromReporting)
                {
                    return(false);
                }

                // if the property is marked virtual (unless it is 'virtual final'), don't include it since it isn't a real database field
                var getter    = p.GetGetMethod();
                var isVirtual = getter?.IsVirtual == true;
                if (isVirtual)
                {
                    // NOTE: Properties that implement interface members (for example Rock.Data.IOrder) will also be marked as 'virtual final' by the compiler, so check IsFinal to determine if it was the compiler that did it.
                    // See https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.isfinal?redirectedfrom=MSDN&view=netframework-4.7.2#System_Reflection_MethodBase_IsFinal
                    bool isVirtualDueToInterface = getter?.IsFinal == true;
                    if (!isVirtualDueToInterface)
                    {
                        return(false);
                    }
                }

                return(true);
            }).ToList();

            // Go thru filteredEntityProperties and create the list of EntityFields that we can include
            foreach (var property in filteredEntityProperties)
            {
                EntityField entityField = new EntityField(property.Name, FieldKind.Property, property);
                entityField.IsPreviewable = property.GetCustomAttributes(typeof(PreviewableAttribute), true).Any();
                var fieldTypeAttribute = property.GetCustomAttribute <Rock.Data.FieldTypeAttribute>();

                // check if we can set it from the fieldTypeAttribute
                if ((fieldTypeAttribute != null) && SetEntityFieldFromFieldTypeAttribute(entityField, fieldTypeAttribute))
                {
                    // intentionally blank, entity field is already setup
                }

                // Enum Properties
                else if (property.PropertyType.IsEnum)
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.SINGLE_SELECT.AsGuid());

                    var list = new List <string>();
                    foreach (var value in Enum.GetValues(property.PropertyType))
                    {
                        list.Add(string.Format("{0}^{1}", value, value.ToString().SplitCase()));
                    }

                    var listSource = string.Join(",", list);
                    entityField.FieldConfig.Add("values", new Field.ConfigurationValue(listSource));
                    entityField.FieldConfig.Add("fieldtype", new Field.ConfigurationValue("rb"));
                }

                // Boolean properties
                else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.BOOLEAN.AsGuid());
                }

                // Datetime properties
                else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime? ))
                {
                    var colAttr = property.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
                    if (colAttr != null && (( ColumnAttribute )colAttr).TypeName == "Date")
                    {
                        entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DATE.AsGuid());
                    }
                    else
                    {
                        entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DATE_TIME.AsGuid());
                    }
                }

                // Decimal properties
                else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal? ))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DECIMAL.AsGuid());
                }

                // Text Properties
                else if (property.PropertyType == typeof(string))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.TEXT.AsGuid());
                }

                // Integer Properties (which may be a DefinedValue)
                else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.INTEGER.AsGuid());

                    var definedValueAttribute = property.GetCustomAttribute <Rock.Data.DefinedValueAttribute>();
                    if (definedValueAttribute != null)
                    {
                        // Defined Value Properties
                        Guid?definedTypeGuid = ((Rock.Data.DefinedValueAttribute)definedValueAttribute).DefinedTypeGuid;
                        if (definedTypeGuid.HasValue)
                        {
                            var definedType = DefinedTypeCache.Get(definedTypeGuid.Value);
                            entityField.Title = definedType != null ? definedType.Name : property.Name.Replace("ValueId", string.Empty).SplitCase();
                            if (definedType != null)
                            {
                                entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DEFINED_VALUE.AsGuid());
                                entityField.FieldConfig.Add("definedtype", new Field.ConfigurationValue(definedType.Id.ToString()));
                            }
                        }
                    }
                }

                if (entityField != null && entityField.FieldType != null)
                {
                    entityFields.Add(entityField);
                }
            }

            // Get Attributes
            var entityTypeCache = EntityTypeCache.Get(entityType, true);

            if (entityTypeCache != null)
            {
                int entityTypeId = entityTypeCache.Id;
                List <AttributeCache> cacheAttributeList;
                if (entity != null)
                {
                    // if a specific entity is set, we only need to get the Attributes that the Entity has
                    if (entity is IHasAttributes)
                    {
                        (entity as IHasAttributes).LoadAttributes();
                        cacheAttributeList = (entity as IHasAttributes).Attributes.Select(a => a.Value).ToList();
                    }
                    else
                    {
                        cacheAttributeList = new List <AttributeCache>();
                    }
                }
                else
                {
                    using (var rockContext = new RockContext())
                    {
                        var qryAttributes = new AttributeService(rockContext).GetByEntityTypeId(entityTypeId);
                        if (entityType == typeof(Group) || entityType == typeof(GroupMember))
                        {
                            // in the case of Group or GroupMember, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                            qryAttributes = qryAttributes
                                            .Where(a =>
                                                   a.EntityTypeQualifierColumn == null ||
                                                   a.EntityTypeQualifierColumn == string.Empty ||
                                                   a.EntityTypeQualifierColumn == "GroupTypeId");
                        }
                        else if (entityType == typeof(ContentChannelItem))
                        {
                            // in the case of ContentChannelItem, show attributes that are entity global, but also ones that are qualified by ContentChannelTypeId or ContentChannelId
                            qryAttributes = qryAttributes
                                            .Where(a =>
                                                   a.EntityTypeQualifierColumn == null ||
                                                   a.EntityTypeQualifierColumn == string.Empty ||
                                                   a.EntityTypeQualifierColumn == "ContentChannelTypeId" ||
                                                   a.EntityTypeQualifierColumn == "ContentChannelId"
                                                   );
                        }
                        else if (entityType == typeof(Rock.Model.Workflow))
                        {
                            // in the case of Workflow, show attributes that are entity global, but also ones that are qualified by WorkflowTypeId (and have a valid WorkflowTypeId)
                            var validWorkflowTypeIds = new WorkflowTypeService(rockContext).Queryable().Select(a => a.Id).ToList().Select(a => a.ToString()).ToList();
                            qryAttributes = qryAttributes
                                            .Where(a =>
                                                   a.EntityTypeQualifierColumn == null ||
                                                   a.EntityTypeQualifierColumn == string.Empty ||
                                                   (a.EntityTypeQualifierColumn == "WorkflowTypeId" && validWorkflowTypeIds.Contains(a.EntityTypeQualifierValue)));
                        }
                        else
                        {
                            qryAttributes = qryAttributes.Where(a => string.IsNullOrEmpty(a.EntityTypeQualifierColumn) && string.IsNullOrEmpty(a.EntityTypeQualifierValue));
                        }

                        cacheAttributeList = qryAttributes.ToAttributeCacheList();
                    }
                }

                foreach (var attributeCache in cacheAttributeList)
                {
                    AddEntityFieldForAttribute(entityFields, attributeCache, limitToFilterableFields);
                }
            }

            // Order the fields by title, name
            int index        = 0;
            var sortedFields = new List <EntityField>();

            foreach (var entityField in entityFields.OrderBy(p => !string.IsNullOrEmpty(p.AttributeEntityTypeQualifierName)).ThenBy(p => p.Title).ThenBy(p => p.Name))
            {
                entityField.Index = index;
                index++;
                sortedFields.Add(entityField);
            }

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[EntityHelper.GetCacheKey(entityType, entity, includeOnlyReportingFields, limitToFilterableFields)] = sortedFields;
            }

            return(sortedFields);
        }
Example #8
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <returns></returns>
        public static List<EntityField> GetEntityFields( Type entityType, bool includeOnlyReportingFields = true )
        {
            if ( _entityFields == null )
            {
                _entityFields = new Dictionary<Type, List<EntityField>>();
            }

            if ( _entityFields.ContainsKey( entityType ) && _entityFields[entityType] != null )
            {
                return _entityFields[entityType];
            }

            var entityFields = new List<EntityField>();

            // Get Properties
            foreach ( var property in entityType.GetProperties() )
            {
                if ( !property.GetGetMethod().IsVirtual || property.Name == "Id" || property.Name == "Guid" || property.Name == "Order" )
                {
                    EntityField entityProperty = null;

                    // Enum Properties
                    if ( property.PropertyType.IsEnum )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    }

                    // Boolean properties
                    if ( property.PropertyType == typeof( bool ) || property.PropertyType == typeof( bool? ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                    }

                    // Date properties
                    if ( property.PropertyType == typeof( DateTime ) || property.PropertyType == typeof( DateTime? ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                    }

                    // Text Properties
                    else if ( property.PropertyType == typeof( string ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                    }

                    // Integer Properties
                    else if ( property.PropertyType == typeof( int ) || property.PropertyType == typeof( int? ) )
                    {
                        var definedValueAttribute = property.GetCustomAttributes( typeof( Rock.Data.DefinedValueAttribute ), true ).FirstOrDefault();

                        if ( definedValueAttribute != null )
                        {
                            // Defined Value Properties
                            entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                            var definedType = DefinedTypeCache.Read( ( (Rock.Data.DefinedValueAttribute)definedValueAttribute ).DefinedTypeGuid );
                            entityProperty.Title = definedType != null ? definedType.Name : property.Name.Replace( "ValueId", string.Empty ).SplitCase();
                            entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                            entityProperty.DefinedTypeGuid = definedType.Guid;
                        }
                        else
                        {
                            entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                            entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                        }
                    }

                    if ( entityProperty != null )
                    {
                        entityProperty.IsPreviewable = property.GetCustomAttributes( typeof( PreviewableAttribute ), true ).Any();
                        if ( includeOnlyReportingFields )
                        {
                            bool isReportable = !property.GetCustomAttributes( typeof( HideFromReportingAttribute ), true ).Any();
                            if ( isReportable )
                            {
                                entityFields.Add( entityProperty );
                            }
                        }
                        else
                        {
                            entityFields.Add( entityProperty );
                        }
                    }
                }
            }

            // Get Attributes
            int entityTypeId = EntityTypeCache.Read( entityType ).Id;
            var rockContext = new RockContext();
            var qryAttributes = new AttributeService( rockContext ).Queryable().Where( a => a.EntityTypeId == entityTypeId );
            if ( entityType == typeof( Group ) )
            {
                // in the case of Group, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                qryAttributes = qryAttributes.Where( a => a.EntityTypeQualifierColumn == string.Empty || a.EntityTypeQualifierColumn == "GroupTypeId" );
            }
            else
            {
                qryAttributes = qryAttributes.Where( a => a.EntityTypeQualifierColumn == string.Empty && a.EntityTypeQualifierValue == string.Empty );
            }

            var attributeList = qryAttributes.ToList();

            foreach ( var attribute in attributeList )
            {
                AddEntityFieldForAttribute( entityFields, AttributeCache.Read( attribute.Id ) );
            }

            int index = 1;
            _entityFields[entityType] = new List<EntityField>();
            foreach ( var entityProperty in entityFields.OrderBy( p => p.Title ).ThenBy( p => p.Name ) )
            {
                entityProperty.Index = index;
                index += entityProperty.ControlCount;
                _entityFields[entityType].Add( entityProperty );
            }

            return _entityFields[entityType];
        }
Example #9
0
        /// <summary>
        /// Adds the entity field for attribute.
        /// </summary>
        /// <param name="entityFields">The entity fields.</param>
        /// <param name="attribute">The attribute.</param>
        public static void AddEntityFieldForAttribute( List<EntityField> entityFields, AttributeCache attribute )
        {
            // Ensure prop name is unique
            string propName = attribute.Name;
            int i = 1;
            while ( entityFields.Any( p => p.Name.Equals( propName, StringComparison.CurrentCultureIgnoreCase ) ) )
            {
                propName = attribute.Name + ( i++ ).ToString();
            }

            EntityField entityProperty = null;

            var fieldType = FieldTypeCache.Read( attribute.FieldTypeId );
            string fieldTypeUpperGuid = fieldType.Guid.ToString().ToUpper();

            switch ( fieldTypeUpperGuid )
            {
                case SystemGuid.FieldType.BOOLEAN:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                    break;

                case SystemGuid.FieldType.DATE:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                    break;

                case SystemGuid.FieldType.TIME:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.TIME;
                    break;

                case SystemGuid.FieldType.INTEGER:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                    break;

                case SystemGuid.FieldType.DECIMAL:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.DECIMAL;
                    break;

                case SystemGuid.FieldType.DAY_OF_WEEK:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.DAY_OF_WEEK;
                    break;

                case SystemGuid.FieldType.MULTI_SELECT:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    break;

                case SystemGuid.FieldType.SINGLE_SELECT:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    break;

                case SystemGuid.FieldType.TEXT:
                    entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Guid );
                    entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                    break;
            }

            if ( entityProperty != null )
            {
                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( Group ) ) && attribute.EntityTypeQualifierColumn == "GroupTypeId" )
                {
                    var groupType = new GroupTypeService( new RockContext() ).Get( attribute.EntityTypeQualifierValue.AsInteger() );
                    if ( groupType != null )
                    {
                        entityProperty.Title = string.Format( "{0} ({1})", attribute.Name.SplitCase(), groupType.Name );
                    }
                }

                entityFields.Add( entityProperty );
            }
        }
Example #10
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static List<EntityField> GetEntityFields( Type entityType )
        {
            var entityFields = new List<EntityField>();

            // Get Properties
            foreach ( var property in entityType.GetProperties() )
            {
                if ( !property.GetGetMethod().IsVirtual || property.Name == "Id" || property.Name == "Guid" || property.Name == "Order" )
                {
                    EntityField entityProperty = null;

                    // Enum Properties
                    if ( property.PropertyType.IsEnum )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    }

                    // Boolean properties
                    if ( property.PropertyType == typeof( bool ) || property.PropertyType == typeof( bool? ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                    }

                    // Date properties
                    if ( property.PropertyType == typeof( DateTime ) || property.PropertyType == typeof( DateTime? ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                    }

                    // Text Properties
                    else if ( property.PropertyType == typeof( string ) )
                    {
                        entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                    }

                    // Integer Properties
                    else if ( property.PropertyType == typeof( int ) || property.PropertyType == typeof( int? ) )
                    {
                        var definedValueAttribute = property.GetCustomAttributes( typeof( Rock.Data.DefinedValueAttribute ), true ).FirstOrDefault();

                        if ( definedValueAttribute != null )
                        {
                            // Defined Value Properties
                            entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 1 );
                            var definedType = DefinedTypeCache.Read( ( (Rock.Data.DefinedValueAttribute)definedValueAttribute ).DefinedTypeGuid );
                            entityProperty.Title = definedType != null ? definedType.Name : property.Name.Replace( "ValueId", string.Empty ).SplitCase();
                            entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                            entityProperty.DefinedTypeId = definedType.Id;
                        }
                        else
                        {
                            entityProperty = new EntityField( property.Name, FieldKind.Property, property.PropertyType, 2 );
                            entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                        }
                    }

                    if ( entityProperty != null )
                    {
                        entityProperty.IsPreviewable = property.GetCustomAttributes( typeof( PreviewableAttribute ), true ).Any();
                        entityFields.Add( entityProperty );
                    }
                }
            }

            // Get Attributes
            int entityTypeId = EntityTypeCache.Read( entityType ).Id;
            foreach ( var attribute in new AttributeService().Get( entityTypeId, string.Empty, string.Empty ) )
            {
                // Ensure prop name is unique
                string propName = attribute.Name;
                int i = 1;
                while ( entityFields.Any( p => p.Name.Equals( propName, StringComparison.CurrentCultureIgnoreCase ) ) )
                {
                    propName = attribute.Name + ( i++ ).ToString();
                }

                EntityField entityProperty = null;

                switch ( FieldTypeCache.Read(attribute.FieldTypeId).Guid.ToString().ToUpper() )
                {
                    case SystemGuid.FieldType.BOOLEAN:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                        break;

                    case SystemGuid.FieldType.DATE:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                        break;

                    case SystemGuid.FieldType.INTEGER:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                        break;

                    case SystemGuid.FieldType.MULTI_SELECT:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                        break;

                    case SystemGuid.FieldType.SINGLE_SELECT:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 1, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                        break;

                    case SystemGuid.FieldType.TEXT:
                        entityProperty = new EntityField( attribute.Name, FieldKind.Attribute, null, 2, attribute.Id );
                        entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                        break;
                }

                if ( entityProperty != null )
                {
                    entityFields.Add( entityProperty );
                }
            }

            int index = 1;
            List<EntityField> result = new List<EntityField>();
            foreach ( var entityProperty in entityFields.OrderBy( p => p.Title ).ThenBy( p => p.Name ) )
            {
                entityProperty.Index = index;
                index += entityProperty.ControlCount;
                result.Add( entityProperty );
            }

            return result;
        }
Example #11
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <param name="limitToFilterableFields">if set to <c>true</c> [limit to filterable fields].</param>
        /// <returns></returns>
        public static List<EntityField> GetEntityFields( Type entityType, bool includeOnlyReportingFields = true, bool limitToFilterableFields = true )
        {
            List<EntityField> entityFields = null;
            _workflowTypeNameLookup = null;

            if ( HttpContext.Current != null )
            {
                entityFields = HttpContext.Current.Items[EntityHelper.GetCacheKey(entityType, includeOnlyReportingFields, limitToFilterableFields)] as List<EntityField>;
                if ( entityFields != null )
                {
                    return entityFields;
                }
            }

            if ( entityFields == null )
            {
                entityFields = new List<EntityField>();
            }

            // Find all non-virtual properties or properties that have the [IncludeForReporting] attribute
            var entityProperties = entityType.GetProperties().ToList();
            var filteredEntityProperties = entityProperties
                .Where( p =>
                    !p.GetGetMethod().IsVirtual ||
                    p.GetCustomAttributes( typeof( IncludeForReportingAttribute ), true ).Any() ||
                    p.Name == "Order" )
                .ToList();

            // Get Properties
            foreach ( var property in filteredEntityProperties )
            {
                bool isReportable = !property.GetCustomAttributes( typeof( HideFromReportingAttribute ), true ).Any();
                if ( !includeOnlyReportingFields || isReportable )
                {

                    EntityField entityField = new EntityField( property.Name, FieldKind.Property, property );
                    entityField.IsPreviewable = property.GetCustomAttributes( typeof( PreviewableAttribute ), true ).Any();
                    var fieldTypeAttribute = property.GetCustomAttribute<Rock.Data.FieldTypeAttribute>();

                    // check if we can set it from the fieldTypeAttribute
                    if ( ( fieldTypeAttribute != null ) && SetEntityFieldFromFieldTypeAttribute( entityField, fieldTypeAttribute ) )
                    {
                        // intentially blank, entity field is already setup
                    }

                    // Enum Properties
                    else if ( property.PropertyType.IsEnum )
                    {
                        entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.SINGLE_SELECT.AsGuid() );

                        var list = new List<string>();
                        foreach ( var value in Enum.GetValues( property.PropertyType ) )
                        {
                            list.Add( string.Format( "{0}^{1}", value, value.ToString().SplitCase() ) );
                        }

                        var listSource = string.Join( ",", list );
                        entityField.FieldConfig.Add( "values", new Field.ConfigurationValue( listSource ) );
                        entityField.FieldConfig.Add( "fieldtype", new Field.ConfigurationValue( "rb" ) );
                    }

                    // Boolean properties
                    else if ( property.PropertyType == typeof( bool ) || property.PropertyType == typeof( bool? ) )
                    {
                        entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.BOOLEAN.AsGuid() );
                    }

                    // Datetime properties
                    else if ( property.PropertyType == typeof( DateTime ) || property.PropertyType == typeof( DateTime? ) )
                    {
                        var colAttr = property.GetCustomAttributes( typeof( ColumnAttribute ), true ).FirstOrDefault();
                        if ( colAttr != null && ( (ColumnAttribute)colAttr ).TypeName == "Date" )
                        {
                            entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.DATE.AsGuid() );
                        }
                        else
                        {
                            entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.DATE_TIME.AsGuid() );
                        }
                    }

                    // Decimal properties
                    else if ( property.PropertyType == typeof( decimal ) || property.PropertyType == typeof( decimal? ) )
                    {
                        entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.DECIMAL.AsGuid() );
                    }

                    // Text Properties
                    else if ( property.PropertyType == typeof( string ) )
                    {
                        entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.TEXT.AsGuid() );
                    }

                    // Integer Properties (which may be a DefinedValue)
                    else if ( property.PropertyType == typeof( int ) || property.PropertyType == typeof( int? ) )
                    {
                        entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.INTEGER.AsGuid() );

                        var definedValueAttribute = property.GetCustomAttribute<Rock.Data.DefinedValueAttribute>();
                        if ( definedValueAttribute != null )
                        {
                            // Defined Value Properties
                            Guid? definedTypeGuid = ( (Rock.Data.DefinedValueAttribute)definedValueAttribute ).DefinedTypeGuid;
                            if ( definedTypeGuid.HasValue )
                            {
                                var definedType = DefinedTypeCache.Read( definedTypeGuid.Value );
                                entityField.Title = definedType != null ? definedType.Name : property.Name.Replace( "ValueId", string.Empty ).SplitCase();
                                if ( definedType != null )
                                {
                                    entityField.FieldType = FieldTypeCache.Read( SystemGuid.FieldType.DEFINED_VALUE.AsGuid() );
                                    entityField.FieldConfig.Add( "definedtype", new Field.ConfigurationValue( definedType.Id.ToString() ) );
                                }
                            }
                        }
                    }

                    if ( entityField != null && entityField.FieldType != null )
                    {
                        entityFields.Add( entityField );
                    }
                }
            }

            // Get Attributes
            var entityTypeCache = EntityTypeCache.Read( entityType, true );
            if ( entityTypeCache != null )
            {
                int entityTypeId = entityTypeCache.Id;
                using ( var rockContext = new RockContext() )
                {
                    var qryAttributes = new AttributeService( rockContext ).Queryable().Where( a => a.EntityTypeId == entityTypeId );
                    if ( entityType == typeof( Group ) )
                    {
                        // in the case of Group, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                        qryAttributes = qryAttributes
                            .Where( a =>
                                a.EntityTypeQualifierColumn == null ||
                                a.EntityTypeQualifierColumn == string.Empty ||
                                a.EntityTypeQualifierColumn == "GroupTypeId" );
                    }
                    else if ( entityType == typeof( ContentChannelItem ) )
                    {
                        // in the case of ContentChannelItem, show attributes that are entity global, but also ones that are qualified by ContentChannelTypeId
                        qryAttributes = qryAttributes
                            .Where( a =>
                                a.EntityTypeQualifierColumn == null ||
                                a.EntityTypeQualifierColumn == string.Empty ||
                                a.EntityTypeQualifierColumn == "ContentChannelTypeId" );
                    }
                    else if ( entityType == typeof( Rock.Model.Workflow ) )
                    {
                        // in the case of Workflow, show attributes that are entity global, but also ones that are qualified by WorkflowTypeId (and have a valid WorkflowTypeId)
                        var validWorkflowTypeIds = new WorkflowTypeService(rockContext).Queryable().Select(a=> a.Id).ToList().Select(a => a.ToString()).ToList();
                        qryAttributes = qryAttributes
                            .Where( a =>
                                a.EntityTypeQualifierColumn == null ||
                                a.EntityTypeQualifierColumn == string.Empty ||
                                (a.EntityTypeQualifierColumn == "WorkflowTypeId" && validWorkflowTypeIds.Contains(a.EntityTypeQualifierValue) ));
                    }
                    else
                    {
                        qryAttributes = qryAttributes.Where( a => a.EntityTypeQualifierColumn == string.Empty && a.EntityTypeQualifierValue == string.Empty );
                    }

                    var attributeIdList = qryAttributes.Select( a => a.Id ).ToList();

                    foreach ( var attributeId in attributeIdList )
                    {
                        AddEntityFieldForAttribute( entityFields, AttributeCache.Read( attributeId ), limitToFilterableFields );
                    }
                }
            }

            // Order the fields by title, name
            int index = 0;
            var sortedFields = new List<EntityField>();
            foreach ( var entityField in entityFields.OrderBy( p => !string.IsNullOrEmpty(p.AttributeEntityTypeQualifierName)).ThenBy( p => p.Title ).ThenBy( p => p.Name ) )
            {
                entityField.Index = index;
                index++;
                sortedFields.Add( entityField );
            }

            if ( HttpContext.Current != null )
            {
                HttpContext.Current.Items[EntityHelper.GetCacheKey( entityType, includeOnlyReportingFields, limitToFilterableFields )] = sortedFields;
            }

            return sortedFields;
        }
Example #12
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static List <EntityField> GetEntityFields(Type entityType)
        {
            var entityFields = new List <EntityField>();

            // Get Properties
            foreach (var property in entityType.GetProperties())
            {
                if (!property.GetGetMethod().IsVirtual || property.Name == "Id" || property.Name == "Guid" || property.Name == "Order")
                {
                    EntityField entityProperty = null;

                    // Enum Properties
                    if (property.PropertyType.IsEnum)
                    {
                        entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 1);
                        entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    }

                    // Boolean properties
                    if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
                    {
                        entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 1);
                        entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                    }

                    // Date properties
                    if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime? ))
                    {
                        entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 2);
                        entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                    }

                    // Text Properties
                    else if (property.PropertyType == typeof(string))
                    {
                        entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 2);
                        entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                    }

                    // Integer Properties
                    else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
                    {
                        var definedValueAttribute = property.GetCustomAttributes(typeof(Rock.Data.DefinedValueAttribute), true).FirstOrDefault();

                        if (definedValueAttribute != null)
                        {
                            // Defined Value Properties
                            entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 1);
                            var definedType = DefinedTypeCache.Read(((Rock.Data.DefinedValueAttribute)definedValueAttribute).DefinedTypeGuid);
                            entityProperty.Title           = definedType != null ? definedType.Name : property.Name.Replace("ValueId", string.Empty).SplitCase();
                            entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                            entityProperty.DefinedTypeId   = definedType.Id;
                        }
                        else
                        {
                            entityProperty = new EntityField(property.Name, FieldKind.Property, property.PropertyType, 2);
                            entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                        }
                    }

                    if (entityProperty != null)
                    {
                        entityProperty.IsPreviewable = property.GetCustomAttributes(typeof(PreviewableAttribute), true).Any();
                        entityFields.Add(entityProperty);
                    }
                }
            }

            // Get Attributes
            int entityTypeId = EntityTypeCache.Read(entityType).Id;

            foreach (var attribute in new AttributeService().Get(entityTypeId, string.Empty, string.Empty))
            {
                // Ensure prop name is unique
                string propName = attribute.Name;
                int    i        = 1;
                while (entityFields.Any(p => p.Name.Equals(propName, StringComparison.CurrentCultureIgnoreCase)))
                {
                    propName = attribute.Name + (i++).ToString();
                }

                EntityField entityProperty = null;

                switch (FieldTypeCache.Read(attribute.FieldTypeId).Guid.ToString().ToUpper())
                {
                case SystemGuid.FieldType.BOOLEAN:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 1, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.SINGLE_SELECT;
                    break;

                case SystemGuid.FieldType.DATE:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 2, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.DATE;
                    break;

                case SystemGuid.FieldType.INTEGER:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 2, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.INTEGER;
                    break;

                case SystemGuid.FieldType.MULTI_SELECT:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 1, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    break;

                case SystemGuid.FieldType.SINGLE_SELECT:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 1, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.MULTI_SELECT;
                    break;

                case SystemGuid.FieldType.TEXT:
                    entityProperty = new EntityField(attribute.Name, FieldKind.Attribute, null, 2, attribute.Id);
                    entityProperty.FilterFieldType = SystemGuid.FieldType.TEXT;
                    break;
                }

                if (entityProperty != null)
                {
                    entityFields.Add(entityProperty);
                }
            }

            int index = 1;
            List <EntityField> result = new List <EntityField>();

            foreach (var entityProperty in entityFields.OrderBy(p => p.Title).ThenBy(p => p.Name))
            {
                entityProperty.Index = index;
                index += entityProperty.ControlCount;
                result.Add(entityProperty);
            }

            return(result);
        }
Example #13
0
        /// <summary>
        /// Adds the entity field for attribute.
        /// </summary>
        /// <param name="entityFields">The entity fields.</param>
        /// <param name="attribute">The attribute.</param>
        public static void AddEntityFieldForAttribute( List<EntityField> entityFields, AttributeCache attribute )
        {
            // Ensure prop name is unique
            string propName = attribute.Key;
            int i = 1;
            while ( entityFields.Any( p => p.Name.Equals( propName, StringComparison.CurrentCultureIgnoreCase ) ) )
            {
                propName = attribute.Key + ( i++ ).ToString();
            }

            // Make sure that the attributes field type actually renders a filter control
            var fieldType = FieldTypeCache.Read( attribute.FieldTypeId );
            if ( fieldType != null && fieldType.Field.FilterControl( attribute.QualifierValues, propName, true ) != null )
            {
                var entityField = new EntityField();
                entityField.Name = propName;
                entityField.Title = attribute.Name.SplitCase();
                entityField.FieldKind = FieldKind.Attribute;
                entityField.PropertyType = typeof( string );
                entityField.AttributeGuid = attribute.Guid;
                entityField.FieldType = fieldType;
                foreach ( var config in attribute.QualifierValues )
                {
                    entityField.FieldConfig.Add( config.Key, config.Value );
                }

                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( Group ) ) && attribute.EntityTypeQualifierColumn == "GroupTypeId" )
                {
                    using ( var rockContext = new RockContext() )
                    {
                        var groupType = new GroupTypeService( rockContext ).Get( attribute.EntityTypeQualifierValue.AsInteger() );
                        if ( groupType != null )
                        {
                            entityField.Title = string.Format( "{0} ({1})", attribute.Name, groupType.Name );
                        }
                    }
                }

                entityFields.Add( entityField );
            }
        }
Example #14
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <returns></returns>
        public static List <EntityField> GetEntityFields(Type entityType, bool includeOnlyReportingFields = true)
        {
            List <EntityField> entityFields = null;

            if (HttpContext.Current != null)
            {
                entityFields = HttpContext.Current.Items[string.Format("EntityHelper:GetEntityFields:{0}", entityType.FullName)] as List <EntityField>;
                if (entityFields != null)
                {
                    return(entityFields);
                }
            }

            entityFields = new List <EntityField>();

            // Find all non-virtual properties or properties that have the [IncludeForReporting] attribute
            var entityProperties         = entityType.GetProperties().ToList();
            var filteredEntityProperties = entityProperties
                                           .Where(p =>
                                                  !p.GetGetMethod().IsVirtual ||
                                                  p.GetCustomAttributes(typeof(IncludeForReportingAttribute), true).Any() ||
                                                  p.Name == "Order")
                                           .ToList();

            // Get Properties
            foreach (var property in filteredEntityProperties)
            {
                bool isReportable = !property.GetCustomAttributes(typeof(HideFromReportingAttribute), true).Any();
                if (!includeOnlyReportingFields || isReportable)
                {
                    //
                    // Determine the appropriate Field Type for this Property.
                    //

                    // Check if the Field Type has been explicitly set using an Attribute.
                    string fieldTypeGuidText = null;

                    var reportingFieldAttribute = property.GetCustomAttributes(typeof(Rock.Data.ReportingFieldAttribute), true).FirstOrDefault() as ReportingFieldAttribute;

                    if (reportingFieldAttribute != null)
                    {
                        fieldTypeGuidText = reportingFieldAttribute.FilterFieldTypeGuid.AsGuidOrNull().ToStringSafe();
                    }
                    else
                    {
                        // Infer the Field Type from the Property Type.
                        // Enum Properties
                        if (property.PropertyType.IsEnum)
                        {
                            fieldTypeGuidText = SystemGuid.FieldType.SINGLE_SELECT;
                        }
                        // Boolean properties
                        else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
                        {
                            fieldTypeGuidText = SystemGuid.FieldType.BOOLEAN;
                        }
                        // Datetime properties
                        else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime? ))
                        {
                            var colAttr = property.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
                            if (colAttr != null && ((ColumnAttribute)colAttr).TypeName == "Date")
                            {
                                fieldTypeGuidText = SystemGuid.FieldType.DATE;
                            }
                            else
                            {
                                fieldTypeGuidText = SystemGuid.FieldType.DATE_TIME;
                            }
                        }
                        // Decimal properties
                        else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal? ))
                        {
                            fieldTypeGuidText = SystemGuid.FieldType.DECIMAL;
                        }
                        // Text Properties
                        else if (property.PropertyType == typeof(string))
                        {
                            fieldTypeGuidText = SystemGuid.FieldType.TEXT;
                        }
                        // Integer Properties
                        else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
                        {
                            var definedValueAttribute = property.GetCustomAttributes(typeof(Rock.Data.DefinedValueAttribute), true).FirstOrDefault();
                            if (definedValueAttribute != null)
                            {
                                fieldTypeGuidText = SystemGuid.FieldType.DEFINED_VALUE;
                            }
                            else
                            {
                                fieldTypeGuidText = SystemGuid.FieldType.INTEGER;
                            }
                        }
                    }

                    EntityField entityField = new EntityField(property.Name, FieldKind.Property, property.PropertyType);
                    entityField.IsPreviewable = property.GetCustomAttributes(typeof(PreviewableAttribute), true).Any();

                    entityField.FieldType = FieldTypeCache.Read(fieldTypeGuidText.AsGuid());

                    entityField.IsPreviewable = property.GetCustomAttributes(typeof(ReportingFieldAttribute), true).Any();

                    //
                    // Set additional configuration for some Field Types.
                    //

                    // Single Select Field
                    if (fieldTypeGuidText == SystemGuid.FieldType.SINGLE_SELECT)
                    {
                        var list = new List <string>();
                        foreach (var value in Enum.GetValues(property.PropertyType))
                        {
                            list.Add(string.Format("{0}^{1}", value, value.ToString().SplitCase()));
                        }

                        var listSource = string.Join(",", list);
                        entityField.FieldConfig.Add("values", new Field.ConfigurationValue(listSource));
                        entityField.FieldConfig.Add("fieldtype", new Field.ConfigurationValue("rb"));
                    }
                    // Defined Value Field
                    else if (fieldTypeGuidText == SystemGuid.FieldType.DEFINED_VALUE)
                    {
                        var definedValueAttribute = property.GetCustomAttributes(typeof(Rock.Data.DefinedValueAttribute), true).FirstOrDefault();

                        if (definedValueAttribute != null)
                        {
                            Guid?definedTypeGuid = ((Rock.Data.DefinedValueAttribute)definedValueAttribute).DefinedTypeGuid;
                            if (definedTypeGuid.HasValue)
                            {
                                var definedType = DefinedTypeCache.Read(definedTypeGuid.Value);
                                entityField.Title = definedType != null ? definedType.Name : property.Name.Replace("ValueId", string.Empty).SplitCase();
                                if (definedType != null)
                                {
                                    entityField.FieldConfig.Add("definedtype", new Field.ConfigurationValue(definedType.Id.ToString()));
                                }
                            }
                        }
                    }

                    if (entityField.FieldType != null)
                    {
                        entityFields.Add(entityField);
                    }
                }
            }

            // Get Attributes
            var entityTypeCache = EntityTypeCache.Read(entityType, true);

            if (entityTypeCache != null)
            {
                int entityTypeId = entityTypeCache.Id;
                using (var rockContext = new RockContext())
                {
                    var qryAttributes = new AttributeService(rockContext).Queryable().Where(a => a.EntityTypeId == entityTypeId);
                    if (entityType == typeof(Group))
                    {
                        // in the case of Group, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                        qryAttributes = qryAttributes
                                        .Where(a =>
                                               a.EntityTypeQualifierColumn == null ||
                                               a.EntityTypeQualifierColumn == string.Empty ||
                                               a.EntityTypeQualifierColumn == "GroupTypeId");
                    }
                    else
                    {
                        qryAttributes = qryAttributes.Where(a => a.EntityTypeQualifierColumn == string.Empty && a.EntityTypeQualifierValue == string.Empty);
                    }

                    var attributeIdList = qryAttributes.Select(a => a.Id).ToList();

                    foreach (var attributeId in attributeIdList)
                    {
                        AddEntityFieldForAttribute(entityFields, AttributeCache.Read(attributeId));
                    }
                }
            }

            // Order the fields by title, name
            int index        = 0;
            var sortedFields = new List <EntityField>();

            foreach (var entityField in entityFields.OrderBy(p => p.Title).ThenBy(p => p.Name))
            {
                entityField.Index = index;
                index++;
                sortedFields.Add(entityField);
            }

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[string.Format("EntityHelper:GetEntityFields:{0}", entityType.FullName)] = sortedFields;
            }

            return(sortedFields);
        }
Example #15
0
        /// <summary>
        /// Gets the entity fields.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <param name="limitToFilterableFields">if set to <c>true</c> [limit to filterable fields].</param>
        /// <returns></returns>
        public static List <EntityField> GetEntityFields(Type entityType, bool includeOnlyReportingFields = true, bool limitToFilterableFields = true)
        {
            List <EntityField> entityFields = null;

            _workflowTypeNameLookup = null;

            if (HttpContext.Current != null)
            {
                entityFields = HttpContext.Current.Items[string.Format("EntityHelper:GetEntityFields:{0}", entityType.FullName)] as List <EntityField>;
                if (entityFields != null)
                {
                    return(entityFields);
                }
            }

            if (entityFields == null)
            {
                entityFields = new List <EntityField>();
            }

            // Find all non-virtual properties or properties that have the [IncludeForReporting] attribute
            var entityProperties         = entityType.GetProperties().ToList();
            var filteredEntityProperties = entityProperties
                                           .Where(p =>
                                                  !p.GetGetMethod().IsVirtual ||
                                                  p.GetCustomAttributes(typeof(IncludeForReportingAttribute), true).Any() ||
                                                  p.Name == "Order")
                                           .ToList();

            // Get Properties
            foreach (var property in filteredEntityProperties)
            {
                bool isReportable = !property.GetCustomAttributes(typeof(HideFromReportingAttribute), true).Any();
                if (!includeOnlyReportingFields || isReportable)
                {
                    EntityField entityField = new EntityField(property.Name, FieldKind.Property, property);
                    entityField.IsPreviewable = property.GetCustomAttributes(typeof(PreviewableAttribute), true).Any();
                    var fieldTypeAttribute = property.GetCustomAttribute <Rock.Data.FieldTypeAttribute>();

                    // check if we can set it from the fieldTypeAttribute
                    if ((fieldTypeAttribute != null) && SetEntityFieldFromFieldTypeAttribute(entityField, fieldTypeAttribute))
                    {
                        // intentially blank, entity field is already setup
                    }

                    // Enum Properties
                    else if (property.PropertyType.IsEnum)
                    {
                        entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.SINGLE_SELECT.AsGuid());

                        var list = new List <string>();
                        foreach (var value in Enum.GetValues(property.PropertyType))
                        {
                            list.Add(string.Format("{0}^{1}", value, value.ToString().SplitCase()));
                        }

                        var listSource = string.Join(",", list);
                        entityField.FieldConfig.Add("values", new Field.ConfigurationValue(listSource));
                        entityField.FieldConfig.Add("fieldtype", new Field.ConfigurationValue("rb"));
                    }

                    // Boolean properties
                    else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
                    {
                        entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.BOOLEAN.AsGuid());
                    }

                    // Datetime properties
                    else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime? ))
                    {
                        var colAttr = property.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
                        if (colAttr != null && ((ColumnAttribute)colAttr).TypeName == "Date")
                        {
                            entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.DATE.AsGuid());
                        }
                        else
                        {
                            entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.DATE_TIME.AsGuid());
                        }
                    }

                    // Decimal properties
                    else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal? ))
                    {
                        entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.DECIMAL.AsGuid());
                    }

                    // Text Properties
                    else if (property.PropertyType == typeof(string))
                    {
                        entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.TEXT.AsGuid());
                    }

                    // Integer Properties (which may be a DefinedValue)
                    else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
                    {
                        entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.INTEGER.AsGuid());

                        var definedValueAttribute = property.GetCustomAttribute <Rock.Data.DefinedValueAttribute>();
                        if (definedValueAttribute != null)
                        {
                            // Defined Value Properties
                            Guid?definedTypeGuid = ((Rock.Data.DefinedValueAttribute)definedValueAttribute).DefinedTypeGuid;
                            if (definedTypeGuid.HasValue)
                            {
                                var definedType = DefinedTypeCache.Read(definedTypeGuid.Value);
                                entityField.Title = definedType != null ? definedType.Name : property.Name.Replace("ValueId", string.Empty).SplitCase();
                                if (definedType != null)
                                {
                                    entityField.FieldType = FieldTypeCache.Read(SystemGuid.FieldType.DEFINED_VALUE.AsGuid());
                                    entityField.FieldConfig.Add("definedtype", new Field.ConfigurationValue(definedType.Id.ToString()));
                                }
                            }
                        }
                    }

                    if (entityField != null && entityField.FieldType != null)
                    {
                        entityFields.Add(entityField);
                    }
                }
            }

            // Get Attributes
            var entityTypeCache = EntityTypeCache.Read(entityType, true);

            if (entityTypeCache != null)
            {
                int entityTypeId = entityTypeCache.Id;
                using (var rockContext = new RockContext())
                {
                    var qryAttributes = new AttributeService(rockContext).Queryable().Where(a => a.EntityTypeId == entityTypeId);
                    if (entityType == typeof(Group))
                    {
                        // in the case of Group, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                        qryAttributes = qryAttributes
                                        .Where(a =>
                                               a.EntityTypeQualifierColumn == null ||
                                               a.EntityTypeQualifierColumn == string.Empty ||
                                               a.EntityTypeQualifierColumn == "GroupTypeId");
                    }
                    else if (entityType == typeof(ContentChannelItem))
                    {
                        // in the case of ContentChannelItem, show attributes that are entity global, but also ones that are qualified by ContentChannelTypeId or ContentChannelId
                        qryAttributes = qryAttributes
                                        .Where(a =>
                                               a.EntityTypeQualifierColumn == null ||
                                               a.EntityTypeQualifierColumn == string.Empty ||
                                               a.EntityTypeQualifierColumn == "ContentChannelTypeId" ||
                                               a.EntityTypeQualifierColumn == "ContentChannelId"
                                               );
                    }
                    else if (entityType == typeof(Rock.Model.Workflow))
                    {
                        // in the case of Workflow, show attributes that are entity global, but also ones that are qualified by WorkflowTypeId (and have a valid WorkflowTypeId)
                        var validWorkflowTypeIds = new WorkflowTypeService(rockContext).Queryable().Select(a => a.Id).ToList().Select(a => a.ToString()).ToList();
                        qryAttributes = qryAttributes
                                        .Where(a =>
                                               a.EntityTypeQualifierColumn == null ||
                                               a.EntityTypeQualifierColumn == string.Empty ||
                                               (a.EntityTypeQualifierColumn == "WorkflowTypeId" && validWorkflowTypeIds.Contains(a.EntityTypeQualifierValue)));
                    }
                    else
                    {
                        qryAttributes = qryAttributes.Where(a => a.EntityTypeQualifierColumn == string.Empty && a.EntityTypeQualifierValue == string.Empty);
                    }

                    var attributeIdList = qryAttributes.Select(a => a.Id).ToList();

                    foreach (var attributeId in attributeIdList)
                    {
                        AddEntityFieldForAttribute(entityFields, AttributeCache.Read(attributeId), limitToFilterableFields);
                    }
                }
            }

            // Order the fields by title, name
            int index        = 0;
            var sortedFields = new List <EntityField>();

            foreach (var entityField in entityFields.OrderBy(p => !string.IsNullOrEmpty(p.AttributeEntityTypeQualifierName)).ThenBy(p => p.Title).ThenBy(p => p.Name))
            {
                entityField.Index = index;
                index++;
                sortedFields.Add(entityField);
            }

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[string.Format("EntityHelper:GetEntityFields:{0}", entityType.FullName)] = sortedFields;
            }

            return(sortedFields);
        }
Example #16
0
        /// <summary>
        /// Create an EntityField for an Attribute.
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        /// <param name="limitToFilterableAttributes"></param>
        public static EntityField GetEntityFieldForAttribute( AttributeCache attribute, bool limitToFilterableAttributes = true )
        {
            // Ensure field name only has Alpha, Numeric and underscore chars
            string fieldName = attribute.Key.RemoveSpecialCharacters().Replace( ".", "" );

            EntityField entityField = null;

            // Make sure that the attributes field type actually renders a filter control if limitToFilterableAttributes
            var fieldType = FieldTypeCache.Read( attribute.FieldTypeId );
            if ( fieldType != null && ( !limitToFilterableAttributes || fieldType.Field.HasFilterControl() ) )
            {
                entityField = new EntityField( fieldName, FieldKind.Attribute, typeof( string ), attribute.Guid, fieldType );
                entityField.Title = attribute.Name.SplitCase();
                entityField.TitleWithoutQualifier = entityField.Title;

                foreach ( var config in attribute.QualifierValues )
                {
                    entityField.FieldConfig.Add( config.Key, config.Value );
                }

                // Special processing for Entity Type "Group" to handle sub-types that are distinguished by GroupTypeId.
                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( Group ) ) && attribute.EntityTypeQualifierColumn == "GroupTypeId" )
                {
                    using ( var rockContext = new RockContext() )
                    {
                        var groupType = GroupTypeCache.Read( attribute.EntityTypeQualifierValue.AsInteger(), rockContext );
                        if ( groupType != null )
                        {
                            // Append the Qualifier to the title
                            entityField.AttributeEntityTypeQualifierName = groupType.Name;
                            entityField.Title = string.Format( "{0} ({1})", attribute.Name, groupType.Name );
                        }
                    }
                }

                // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelTypeId.
                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( ContentChannelItem ) ) && attribute.EntityTypeQualifierColumn == "ContentChannelTypeId" )
                {
                    using ( var rockContext = new RockContext() )
                    {
                        var contentChannelType = new ContentChannelTypeService( rockContext ).Get( attribute.EntityTypeQualifierValue.AsInteger() );
                        if ( contentChannelType != null )
                        {
                            // Append the Qualifier to the title
                            entityField.AttributeEntityTypeQualifierName = contentChannelType.Name;
                            entityField.Title = string.Format( "{0} ({1})", attribute.Name, contentChannelType.Name );
                        }
                    }
                }

                // Special processing for Entity Type "Workflow" to handle sub-types that are distinguished by WorkflowTypeId.
                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( Rock.Model.Workflow ) ) && attribute.EntityTypeQualifierColumn == "WorkflowTypeId" )
                {
                    using ( var rockContext = new RockContext() )
                    {
                        int workflowTypeId = attribute.EntityTypeQualifierValue.AsInteger();
                        if (_workflowTypeNameLookup == null)
                        {
                            _workflowTypeNameLookup = new WorkflowTypeService( rockContext ).Queryable().ToDictionary( k => k.Id, v => v.Name );
                        }

                        var workflowTypeName = _workflowTypeNameLookup.ContainsKey( workflowTypeId ) ? _workflowTypeNameLookup[workflowTypeId] : null;
                        if ( workflowTypeName != null )
                        {
                            // Append the Qualifier to the title for Workflow Attributes
                            entityField.AttributeEntityTypeQualifierName = workflowTypeName;
                            entityField.Title = string.Format( "({1}) {0} ", attribute.Name, workflowTypeName );
                        }
                    }
                }
            }

            return entityField;
        }
Example #17
0
        /// <summary>
        /// Gets the entity fields for a specific Entity
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="includeOnlyReportingFields">if set to <c>true</c> [include only reporting fields].</param>
        /// <param name="limitToFilterableFields">if set to <c>true</c> [limit to filterable fields].</param>
        /// <returns></returns>
        public static List <EntityField> GetEntityFields(Type entityType, bool includeOnlyReportingFields = true, bool limitToFilterableFields = true)
        {
            List <EntityField> entityFields = null;

            _workflowTypeNameLookup = null;

            if (HttpContext.Current != null)
            {
                entityFields = HttpContext.Current.Items[EntityHelper.GetCacheKey(entityType, includeOnlyReportingFields, limitToFilterableFields)] as List <EntityField>;
                if (entityFields != null)
                {
                    return(entityFields);
                }
            }

            if (entityFields == null)
            {
                entityFields = new List <EntityField>();
            }

            List <PropertyInfo> entityProperties = entityType.GetProperties().ToList();

            // filter the properties to narrow down the ones that we want to include in EntityFields
            var filteredEntityProperties = entityProperties
                                           .Where((p) =>
            {
                var includeForReportingAttribute = p.GetCustomAttribute <IncludeForReportingAttribute>() != null;

                // if the property has an IncludeForReportingAttribute, include it regardless
                if (includeForReportingAttribute)
                {
                    return(true);
                }

                bool hideFromReporting = false;
                if (includeOnlyReportingFields)
                {
                    hideFromReporting = p.GetCustomAttribute <HideFromReportingAttribute>() != null;
                }

                // if the property should be hidden from reporting, don't show it
                if (hideFromReporting)
                {
                    return(false);
                }

                bool isMappedDatabaseField = Reflection.IsMappedDatabaseProperty(p);
                if (!isMappedDatabaseField)
                {
                    return(false);
                }

                return(true);
            }).ToList();

            // Go thru filteredEntityProperties and create the list of EntityFields that we can include
            foreach (var property in filteredEntityProperties)
            {
                EntityField entityField = new EntityField(property.Name, FieldKind.Property, property);
                entityField.IsPreviewable = property.GetCustomAttributes(typeof(PreviewableAttribute), true).Any();
                var fieldTypeAttribute = property.GetCustomAttribute <Rock.Data.FieldTypeAttribute>();

                // check if we can set it from the fieldTypeAttribute
                if ((fieldTypeAttribute != null) && SetEntityFieldFromFieldTypeAttribute(entityField, fieldTypeAttribute))
                {
                    // intentionally blank, entity field is already setup
                }

                // Enum Properties
                else if (property.PropertyType.IsEnum)
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.SINGLE_SELECT.AsGuid());

                    var list = new List <string>();
                    foreach (var value in Enum.GetValues(property.PropertyType))
                    {
                        list.Add(string.Format("{0}^{1}", value, value.ToString().SplitCase()));
                    }

                    var listSource = string.Join(",", list);
                    entityField.FieldConfig.Add("values", new Field.ConfigurationValue(listSource));
                    entityField.FieldConfig.Add("fieldtype", new Field.ConfigurationValue("rb"));
                }

                // Boolean properties
                else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.BOOLEAN.AsGuid());
                }

                // Datetime properties
                else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime? ))
                {
                    var colAttr = property.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
                    if (colAttr != null && (( ColumnAttribute )colAttr).TypeName == "Date")
                    {
                        entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DATE.AsGuid());
                    }
                    else
                    {
                        entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DATE_TIME.AsGuid());
                    }
                }

                // Decimal properties
                else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal? ))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DECIMAL.AsGuid());
                }

                // Text Properties
                else if (property.PropertyType == typeof(string))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.TEXT.AsGuid());
                }

                // Integer Properties (which may be a DefinedValue)
                else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
                {
                    entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.INTEGER.AsGuid());

                    var definedValueAttribute = property.GetCustomAttribute <Rock.Data.DefinedValueAttribute>();
                    if (definedValueAttribute != null)
                    {
                        // Defined Value Properties
                        Guid?definedTypeGuid = definedValueAttribute.DefinedTypeGuid;
                        if (definedTypeGuid.HasValue)
                        {
                            var definedType = DefinedTypeCache.Get(definedTypeGuid.Value);
                            entityField.Title = definedType != null ? definedType.Name : property.Name.Replace("ValueId", string.Empty).SplitCase();
                            if (definedType != null)
                            {
                                entityField.FieldType = FieldTypeCache.Get(SystemGuid.FieldType.DEFINED_VALUE.AsGuid());
                                entityField.FieldConfig.Add("definedtype", new Field.ConfigurationValue(definedType.Id.ToString()));
                            }
                        }
                    }
                }

                if (entityField != null && entityField.FieldType != null)
                {
                    entityFields.Add(entityField);
                }
            }

            // Get Attributes
            var entityTypeCache = EntityTypeCache.Get(entityType, true);

            if (entityTypeCache != null)
            {
                int entityTypeId = entityTypeCache.Id;

                var entityAttributesCache = AttributeCache.GetByEntity(entityTypeCache.Id);

                List <AttributeCache> cacheAttributeList = entityAttributesCache.SelectMany(a => a.AttributeIds).Distinct().Select(a => AttributeCache.Get(a)).ToList();

                if (entityType == typeof(Group) || entityType == typeof(GroupMember))
                {
                    // in the case of Group or GroupMember, show attributes that are entity global, but also ones that are qualified by GroupTypeId
                    cacheAttributeList = cacheAttributeList
                                         .Where(a =>
                                                a.EntityTypeQualifierColumn == null ||
                                                a.EntityTypeQualifierColumn == string.Empty ||
                                                a.EntityTypeQualifierColumn == "GroupTypeId").ToList();
                }
                else if (entityType == typeof(ConnectionRequest))
                {
                    // in the case of Connection Requests, show attributes that are entity global, but also ones that are qualified by ConnectionOpportunityId
                    cacheAttributeList = cacheAttributeList
                                         .Where(a =>
                                                a.EntityTypeQualifierColumn == null ||
                                                a.EntityTypeQualifierColumn == string.Empty ||
                                                a.EntityTypeQualifierColumn == "ConnectionOpportunityId"
                                                ).ToList();
                }
                else if (entityType == typeof(Registration))
                {
                    // in the case of Registrations, show attributes that are entity global, but also ones that are qualified by RegistrationTemplateId
                    cacheAttributeList = cacheAttributeList
                                         .Where(a =>
                                                a.EntityTypeQualifierColumn == null ||
                                                a.EntityTypeQualifierColumn == string.Empty ||
                                                a.EntityTypeQualifierColumn == "RegistrationTemplateId"
                                                ).ToList();
                }
                else if (entityType == typeof(ContentChannelItem))
                {
                    // in the case of ContentChannelItem, show attributes that are entity global, but also ones that are qualified by ContentChannelTypeId or ContentChannelId
                    cacheAttributeList = cacheAttributeList
                                         .Where(a =>
                                                a.EntityTypeQualifierColumn == null ||
                                                a.EntityTypeQualifierColumn == string.Empty ||
                                                a.EntityTypeQualifierColumn == "ContentChannelTypeId" ||
                                                a.EntityTypeQualifierColumn == "ContentChannelId"
                                                ).ToList();
                }
                else if (entityType == typeof(Rock.Model.Workflow))
                {
                    // in the case of Workflow, show attributes that are entity global, but also ones that are qualified by WorkflowTypeId (and have a valid WorkflowTypeId)
                    var validWorkflowTypeIds = WorkflowTypeCache.All().Select(a => a.Id.ToString()).ToArray();
                    cacheAttributeList = cacheAttributeList
                                         .Where(a =>
                                                a.EntityTypeQualifierColumn == null ||
                                                a.EntityTypeQualifierColumn == string.Empty ||
                                                (a.EntityTypeQualifierColumn == "WorkflowTypeId" && validWorkflowTypeIds.Contains(a.EntityTypeQualifierValue))).ToList();
                }
                else
                {
                    cacheAttributeList = cacheAttributeList.Where(a => string.IsNullOrEmpty(a.EntityTypeQualifierColumn) && string.IsNullOrEmpty(a.EntityTypeQualifierValue)).ToList();
                }

                EntityHelper.AddEntityFieldsForAttributeList(entityFields, cacheAttributeList);
            }

            // Order the fields by title, name
            int index        = 0;
            var sortedFields = new List <EntityField>();

            foreach (var entityField in entityFields.OrderBy(p => !string.IsNullOrEmpty(p.AttributeEntityTypeQualifierName)).ThenBy(p => p.Title).ThenBy(p => p.Name))
            {
                entityField.Index = index;
                index++;
                sortedFields.Add(entityField);
            }

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[EntityHelper.GetCacheKey(entityType, includeOnlyReportingFields, limitToFilterableFields)] = sortedFields;
            }

            return(sortedFields);
        }
Example #18
0
        /// <summary>
        /// Sets the entity field from field type attribute.
        /// </summary>
        /// <param name="entityField">The entity field.</param>
        /// <param name="fieldTypeAttribute">The field type attribute.</param>
        /// <returns></returns>
        private static bool SetEntityFieldFromFieldTypeAttribute( EntityField entityField, FieldTypeAttribute fieldTypeAttribute )
        {
            if ( fieldTypeAttribute != null )
            {
                var fieldTypeCache = FieldTypeCache.Read( fieldTypeAttribute.FieldTypeGuid );
                if ( fieldTypeCache != null && fieldTypeCache.Field != null )
                {
                    if ( fieldTypeCache.Field.HasFilterControl() )
                    {
                        if ( entityField.Title.EndsWith( " Id" ) )
                        {
                            entityField.Title = entityField.Title.ReplaceLastOccurrence( " Id", string.Empty );
                        }

                        entityField.FieldType = fieldTypeCache;
                        if ( fieldTypeAttribute.ConfigurationKey != null && fieldTypeAttribute.ConfigurationValue != null )
                        {
                            entityField.FieldConfig.Add( fieldTypeAttribute.ConfigurationKey, new ConfigurationValue( fieldTypeAttribute.ConfigurationValue ) );
                        }

                        return true;
                    }
                }
            }

            return false;
        }
Example #19
0
        /// <summary>
        /// Adds the entity field for attribute.
        /// </summary>
        /// <param name="entityFields">The entity fields.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="limitToFilterableAttributes">if set to <c>true</c> [limit to filterable attributes].</param>
        public static void AddEntityFieldForAttribute( List<EntityField> entityFields, AttributeCache attribute, bool limitToFilterableAttributes = true )
        {
            // Ensure prop name only has Alpha, Numeric and underscore chars
            string propName = attribute.Key.RemoveSpecialCharacters().Replace( ".", "" );

            // Ensure prop name is unique
            int i = 1;
            while ( entityFields.Any( p => p.Name.Equals( propName, StringComparison.CurrentCultureIgnoreCase ) ) )
            {
                propName = attribute.Key + ( i++ ).ToString();
            }

            // Make sure that the attributes field type actually renders a filter control if limitToFilterableAttributes
            var fieldType = FieldTypeCache.Read( attribute.FieldTypeId );
            if ( fieldType != null && ( !limitToFilterableAttributes || fieldType.Field.HasFilterControl() ) )
            {
                var entityField = new EntityField( propName, FieldKind.Attribute, typeof( string ), attribute.Guid, fieldType );
                entityField.Title = attribute.Name.SplitCase();

                foreach ( var config in attribute.QualifierValues )
                {
                    entityField.FieldConfig.Add( config.Key, config.Value );
                }

                if ( attribute.EntityTypeId == EntityTypeCache.GetId( typeof( Group ) ) && attribute.EntityTypeQualifierColumn == "GroupTypeId" )
                {
                    using ( var rockContext = new RockContext() )
                    {
                        var groupType = new GroupTypeService( rockContext ).Get( attribute.EntityTypeQualifierValue.AsInteger() );
                        if ( groupType != null )
                        {
                            entityField.Title = string.Format( "{0} ({1})", attribute.Name, groupType.Name );
                        }
                    }
                }

                entityFields.Add( entityField );
            }
        }