Ejemplo n.º 1
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;

            _workflowTypeNameLookup = null;

            _entityFieldsLookup = _entityFieldsLookup ?? new Dictionary <string, List <EntityField> >();
            entityFields        = _entityFieldsLookup.GetValueOrNull(EntityHelper.GetCacheKey(entityType, entity, includeOnlyReportingFields, limitToFilterableFields));
            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;
                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(ConnectionRequest))
                        {
                            // in the case of Connection Requests, show attributes that are entity global, but also ones that are qualified by ConnectionOpportunityId
                            qryAttributes = qryAttributes
                                            .Where(a =>
                                                   a.EntityTypeQualifierColumn == null ||
                                                   a.EntityTypeQualifierColumn == string.Empty ||
                                                   a.EntityTypeQualifierColumn == "ConnectionOpportunityId"
                                                   );
                        }
                        else if (entityType == typeof(Registration))
                        {
                            // in the case of Registrations, show attributes that are entity global, but also ones that are qualified by RegistrationTemplateId
                            qryAttributes = qryAttributes
                                            .Where(a =>
                                                   a.EntityTypeQualifierColumn == null ||
                                                   a.EntityTypeQualifierColumn == string.Empty ||
                                                   a.EntityTypeQualifierColumn == "RegistrationTemplateId"
                                                   );
                        }
                        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();
                    }
                }

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

            _entityFieldsLookup.AddOrReplace(EntityHelper.GetCacheKey(entityType, entity, includeOnlyReportingFields, limitToFilterableFields), sortedFields);

            return(sortedFields);
        }
        /// <summary>
        /// Gets the filter list recursive.
        /// </summary>
        /// <param name="filterList">The filter list.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="reportEntityType">Type of the report entity.</param>
        private static void GetFilterListRecursive(List <FilterInfo> filterList, DataViewFilter filter, EntityType reportEntityType)
        {
            var result = new Dictionary <Guid, string>();

            var entityType            = EntityTypeCache.Get(filter.EntityTypeId ?? 0);
            var reportEntityTypeCache = EntityTypeCache.Get(reportEntityType);
            var reportEntityTypeModel = reportEntityTypeCache.GetEntityType();

            var filterInfo = new FilterInfo(filter);

            filterInfo.FilterList = filterList;

            if (entityType != null)
            {
                var component = Rock.Reporting.DataFilterContainer.GetComponent(entityType.Name);
                filterInfo.Component             = component;
                filterInfo.ReportEntityTypeModel = reportEntityTypeModel;

                if (component != null)
                {
                    if (component is Rock.Reporting.DataFilter.EntityFieldFilter)
                    {
                        var entityFieldFilter = component as Rock.Reporting.DataFilter.EntityFieldFilter;
                        var fieldName         = entityFieldFilter.GetSelectedFieldName(filter.Selection);
                        if (!string.IsNullOrWhiteSpace(fieldName))
                        {
                            var entityFields = EntityHelper.GetEntityFields(reportEntityTypeModel);
                            var entityField  = entityFields.Where(a => a.Name == fieldName).FirstOrDefault();
                            if (entityField != null)
                            {
                                filterInfo.Title = entityField.Title;
                            }
                            else
                            {
                                filterInfo.Title = fieldName;
                            }
                        }
                    }
                    else
                    {
                        filterInfo.Title = component.GetTitle(reportEntityType.GetType());
                    }
                }
            }

            filterList.Add(filterInfo);

            if (filterInfo.Component is Rock.Reporting.DataFilter.OtherDataViewFilter)
            {
                Rock.Reporting.DataFilter.OtherDataViewFilter otherDataViewFilter = filterInfo.Component as Rock.Reporting.DataFilter.OtherDataViewFilter;
                var otherDataView = otherDataViewFilter.GetSelectedDataView(filterInfo.Selection);
                if (otherDataView != null)
                {
                    var otherDataViewFilterList = new List <FilterInfo>();
                    GetFilterListRecursive(otherDataViewFilterList, otherDataView.DataViewFilter, reportEntityType);
                    foreach (var otherFilter in otherDataViewFilterList)
                    {
                        if (otherFilter.FromOtherDataView == null)
                        {
                            otherFilter.FromOtherDataView = otherDataView.Name;
                        }
                    }

                    filterList.AddRange(otherDataViewFilterList);
                }
            }

            foreach (var childFilter in filter.ChildFilters)
            {
                GetFilterListRecursive(filterList, childFilter, reportEntityType);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds from field selection in a way that is backwards compatible with filters saved using pre-v1.7 and pre-v1.1 versions of Rock
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="fieldSelection">The field selection.</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 EntityField FindFromFilterSelection(Type entityType, string fieldSelection, bool includeOnlyReportingFields = true, bool limitToFilterableFields = true)
        {
            var entityFields = EntityHelper.GetEntityFields(entityType, includeOnlyReportingFields, limitToFilterableFields);

            return(entityFields.FindFromFilterSelection(fieldSelection));
        }