Beispiel #1
0
        /// <summary>
        /// Filters the results.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="service">The service.</param>
        /// <param name="itemQry">The item qry.</param>
        /// <returns></returns>
        private IQueryable <ContentChannelItem> FilterResults(RockContext rockContext, ContentChannelItemService service, IQueryable <ContentChannelItem> itemQry)
        {
            var contentChannelId = GetAttributeValue(AttributeKeys.ContentChannel).AsInteger();
            var itemType         = typeof(Rock.Model.ContentChannelItem);
            var paramExpression  = service.ParameterExpression;

            //
            // Apply Data Filter.
            //
            int?dataFilterId = GetAttributeValue(AttributeKeys.FilterId).AsIntegerOrNull();

            if (dataFilterId.HasValue)
            {
                var        dataFilterService = new DataViewFilterService(rockContext);
                var        dataFilter        = dataFilterService.Queryable("ChildFilters").FirstOrDefault(a => a.Id == dataFilterId.Value);
                var        errorMessages     = new List <string>();
                Expression whereExpression   = dataFilter?.GetExpression(itemType, service, paramExpression, errorMessages);

                itemQry = itemQry.Where(paramExpression, whereExpression, null);
            }

            //
            // Apply page parameter filtering.
            //
            var pageParameters = RequestContext.GetPageParameters();

            if (GetAttributeValue(AttributeKeys.QueryParameterFiltering).AsBoolean() && pageParameters.Count > 0)
            {
                var propertyFilter = new Rock.Reporting.DataFilter.PropertyFilter();

                foreach (var kvp in pageParameters)
                {
                    var selection = new List <string>();

                    // Since there could be many matches by the key name for an attribute we have to construct the unique name used by EntityHelper.FindFromFilterSelection and use that
                    var attributeService = new AttributeService(rockContext);
                    var attributeGuid    = attributeService
                                           .Queryable()
                                           .Where(a => a.EntityTypeQualifierColumn == "ContentChannelId")
                                           .Where(a => a.EntityTypeQualifierValue == contentChannelId.ToString())
                                           .Where(a => a.Key == kvp.Key)
                                           .Select(a => a.Guid)
                                           .FirstOrDefault();

                    string uniqueName = kvp.Key;
                    if (attributeGuid != null)
                    {
                        uniqueName = string.Format("Attribute_{0}_{1}", kvp.Key, attributeGuid.ToString().Replace("-", string.Empty));
                    }

                    // Keep using uniquename for attributes since common keys (e.g. "category")will return mutliple values
                    selection.Add(uniqueName);

                    var entityField = Rock.Reporting.EntityHelper.FindFromFilterSelection(itemType, uniqueName, false, false);
                    if (entityField != null)
                    {
                        string value = kvp.Value;
                        switch (entityField.FieldType.Guid.ToString().ToUpper())
                        {
                        case Rock.SystemGuid.FieldType.DAY_OF_WEEK:
                        case Rock.SystemGuid.FieldType.SINGLE_SELECT:
                        {
                            selection.Add(value);
                        }
                        break;

                        case Rock.SystemGuid.FieldType.MULTI_SELECT:
                        {
                            selection.Add(ComparisonType.Contains.ConvertToInt().ToString());
                            selection.Add(value);
                        }
                        break;

                        default:
                        {
                            selection.Add(ComparisonType.EqualTo.ConvertToInt().ToString());
                            selection.Add(value);
                        }
                        break;
                        }

                        itemQry = itemQry.Where(paramExpression, propertyFilter.GetExpression(itemType, service, paramExpression, selection.ToJson()));
                    }
                }
            }

            return(itemQry);
        }
        private List<ContentChannelItem> GetContent( List<string> errorMessages )
        {
            var items = GetCacheItem( CONTENT_CACHE_KEY ) as List<ContentChannelItem>;
            bool queryParameterFiltering = GetAttributeValue( "QueryParameterFiltering" ).AsBoolean( false );

            if ( items == null || ( queryParameterFiltering && Request.QueryString.Count > 0 ) )
            {
                Guid? channelGuid = GetAttributeValue( "Channel" ).AsGuidOrNull();
                if ( channelGuid.HasValue )
                {
                    var rockContext = new RockContext();
                    var service = new ContentChannelItemService( rockContext );
                    var itemType = typeof( Rock.Model.ContentChannelItem );
                    
                    ParameterExpression paramExpression = service.ParameterExpression;

                    var contentChannel = new ContentChannelService( rockContext ).Get( channelGuid.Value );
                    if ( contentChannel != null )
                    {
                        var entityFields = HackEntityFields( contentChannel, rockContext );

                        if ( items == null )
                        {
                            items = new List<ContentChannelItem>();

                            var qry = service.Queryable( "ContentChannel,ContentChannelType" );

                            int? itemId = PageParameter( "Item" ).AsIntegerOrNull();
                            if ( queryParameterFiltering && itemId.HasValue )
                            {
                                qry = qry.Where( i => i.Id == itemId.Value );
                            }
                            else
                            {
                                qry = qry.Where( i => i.ContentChannelId == contentChannel.Id );

                                if ( contentChannel.RequiresApproval )
                                {
                                    // Check for the configured status and limit query to those
                                    var statuses = new List<ContentChannelItemStatus>();

                                    foreach ( string statusVal in ( GetAttributeValue( "Status" ) ?? "2" ).Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ) )
                                    {
                                        var status = statusVal.ConvertToEnumOrNull<ContentChannelItemStatus>();
                                        if ( status != null )
                                        {
                                            statuses.Add( status.Value );
                                        }
                                    }
                                    if ( statuses.Any() )
                                    {
                                        qry = qry.Where( i => statuses.Contains( i.Status ) );
                                    }
                                }

                                int? dataFilterId = GetAttributeValue( "FilterId" ).AsIntegerOrNull();
                                if ( dataFilterId.HasValue )
                                {
                                    var dataFilterService = new DataViewFilterService( rockContext );
                                    var dataFilter = dataFilterService.Queryable( "ChildFilters" ).FirstOrDefault( a => a.Id == dataFilterId.Value );
                                    Expression whereExpression = dataFilter != null ? dataFilter.GetExpression( itemType, service, paramExpression, errorMessages ) : null;

                                    qry = qry.Where( paramExpression, whereExpression, null );
                                }
                            }

                            // All filtering has been added, now run query and load attributes
                            foreach ( var item in qry.ToList() )
                            {
                                item.LoadAttributes( rockContext );
                                items.Add( item );
                            }

                            // Order the items
                            SortProperty sortProperty = null;

                            string orderBy = GetAttributeValue( "Order" );
                            if ( !string.IsNullOrWhiteSpace( orderBy ) )
                            {
                                var fieldDirection = new List<string>();
                                foreach ( var itemPair in orderBy.Split( new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries ).Select( a => a.Split( '^' ) ) )
                                {
                                    if ( itemPair.Length == 2 && !string.IsNullOrWhiteSpace( itemPair[0] ) )
                                    {
                                        var sortDirection = SortDirection.Ascending;
                                        if ( !string.IsNullOrWhiteSpace( itemPair[1] ) )
                                        {
                                            sortDirection = itemPair[1].ConvertToEnum<SortDirection>( SortDirection.Ascending );
                                        }
                                        fieldDirection.Add( itemPair[0] + ( sortDirection == SortDirection.Descending ? " desc" : "" ) );
                                    }
                                }

                                sortProperty = new SortProperty();
                                sortProperty.Direction = SortDirection.Ascending;
                                sortProperty.Property = fieldDirection.AsDelimited( "," );

                                string[] columns = sortProperty.Property.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries );

                                var itemQry = items.AsQueryable();
                                IOrderedQueryable<ContentChannelItem> orderedQry = null;

                                for ( int columnIndex = 0; columnIndex < columns.Length; columnIndex++ )
                                {
                                    string column = columns[columnIndex].Trim();

                                    var direction = sortProperty.Direction;
                                    if ( column.ToLower().EndsWith( " desc" ) )
                                    {
                                        column = column.Left( column.Length - 5 );
                                        direction = sortProperty.Direction == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
                                    }

                                    try
                                    {
                                        if ( column.StartsWith( "Attribute:" ) )
                                        {
                                            string attributeKey = column.Substring( 10 );

                                            if ( direction == SortDirection.Ascending )
                                            {
                                                orderedQry = ( columnIndex == 0 ) ?
                                                    itemQry.OrderBy( i => i.AttributeValues.Where( v => v.Key == attributeKey ).FirstOrDefault().Value.SortValue ) :
                                                    orderedQry.ThenBy( i => i.AttributeValues.Where( v => v.Key == attributeKey ).FirstOrDefault().Value.SortValue );
                                            }
                                            else
                                            {
                                                orderedQry = ( columnIndex == 0 ) ?
                                                    itemQry.OrderByDescending( i => i.AttributeValues.Where( v => v.Key == attributeKey ).FirstOrDefault().Value.SortValue ) :
                                                    orderedQry.ThenByDescending( i => i.AttributeValues.Where( v => v.Key == attributeKey ).FirstOrDefault().Value.SortValue );
                                            }
                                        }
                                        else
                                        {
                                            if ( direction == SortDirection.Ascending )
                                            {
                                                orderedQry = ( columnIndex == 0 ) ? itemQry.OrderBy( column ) : orderedQry.ThenBy( column );
                                            }
                                            else
                                            {
                                                orderedQry = ( columnIndex == 0 ) ? itemQry.OrderByDescending( column ) : orderedQry.ThenByDescending( column );
                                            }
                                        }
                                    }
                                    catch { }

                                }

                                try
                                {
                                    if ( orderedQry != null )
                                    {
                                        items = orderedQry.ToList();
                                    }
                                }
                                catch { }

                            }

                            int? cacheDuration = GetAttributeValue( "CacheDuration" ).AsInteger();
                            if ( cacheDuration > 0 )
                            {
                                var cacheItemPolicy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddSeconds( cacheDuration.Value ) };
                                AddCacheItem( CONTENT_CACHE_KEY, items, cacheItemPolicy );
                            }
                        }


                        // If items could be filtered by querystring values, check for filters
                        if ( queryParameterFiltering )
                        {
                            var pageParameters = PageParameters();
                            if ( pageParameters.Count > 0 )
                            {
                                var propertyFilter = new Rock.Reporting.DataFilter.PropertyFilter();

                                var itemQry = items.AsQueryable();
                                foreach ( string key in PageParameters().Select( p => p.Key ).ToList() )
                                {
                                    var selection = new List<string>();
                                    selection.Add( key );

                                    var entityField = entityFields.FirstOrDefault( f => f.Name.Equals( key, StringComparison.OrdinalIgnoreCase ) );
                                    if ( entityField != null )
                                    {
                                        string value = PageParameter( key );
                                        switch ( entityField.FieldType.Guid.ToString().ToUpper() )
                                        {
                                            case Rock.SystemGuid.FieldType.DAY_OF_WEEK:
                                            case Rock.SystemGuid.FieldType.SINGLE_SELECT:
                                                {
                                                    selection.Add( value );
                                                }
                                                break;
                                            case Rock.SystemGuid.FieldType.MULTI_SELECT:
                                                {
                                                    selection.Add( ComparisonType.Contains.ConvertToInt().ToString() );
                                                    selection.Add( value );
                                                }
                                                break;
                                            default:
                                                {
                                                    selection.Add( ComparisonType.EqualTo.ConvertToInt().ToString() );
                                                    selection.Add( value );
                                                }
                                                break;
                                        }

                                        itemQry = itemQry.Where( paramExpression, propertyFilter.GetExpression( itemType, service, paramExpression, Newtonsoft.Json.JsonConvert.SerializeObject( selection ) ) );
                                    }
                                }

                                items = itemQry.ToList();

                            }
                        }
                    }
                }
            }

            return items;

        }