/// <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); }