public IEnumerable <ContentItem> GetContentItems(int queryId, ContentPart part, int skip = 0, int count = 0) { var availableSortCriteria = DescribeSortCriteria().ToList(); var queryRecord = _queryRepository.Get(queryId); if (queryRecord == null) { throw new ArgumentException("queryId"); } var contentItems = new List <ContentItem>(); // prepares tokens Dictionary <string, object> tokens = new Dictionary <string, object>(); if (part != null) { tokens.Add("Content", part.ContentItem); } // aggregate the result for each group query foreach (var contentQuery in GetContentQueries(queryRecord, queryRecord.SortCriteria.OrderBy(sc => sc.Position), tokens)) { contentItems.AddRange(contentQuery.Slice(skip, count)); } if (queryRecord.FilterGroups.Count <= 1) { return(contentItems); } // re-executing the sorting with the cumulated groups var ids = contentItems.Select(c => c.Id).ToArray(); if (ids.Length == 0) { return(Enumerable.Empty <ContentItem>()); } var groupQuery = _contentManager.HqlQuery().Where(alias => alias.Named("ci"), x => x.InG("Id", ids)); // iterate over each sort criteria to apply the alterations to the query object foreach (var sortCriterion in queryRecord.SortCriteria.OrderBy(s => s.Position)) { var sortCriterionContext = new SortCriterionContext { Query = groupQuery, State = FormParametersHelper.ToDynamic(sortCriterion.State), QueryPartRecord = queryRecord }; string category = sortCriterion.Category; string type = sortCriterion.Type; // look for the specific filter component var descriptor = availableSortCriteria.SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Sort(sortCriterionContext); groupQuery = sortCriterionContext.Query; } return(groupQuery.Slice(skip, count)); }
public IEnumerable <IHqlQuery> GetContentQueries(QueryPartRecord queryRecord, IEnumerable <SortCriterionRecord> sortCriteria) { var availableFilters = DescribeFilters().ToList(); var availableSortCriteria = DescribeSortCriteria().ToList(); // pre-executing all groups foreach (var group in queryRecord.FilterGroups) { var contentQuery = _contentManager.HqlQuery().ForVersion(VersionOptions.Published); // iterate over each filter to apply the alterations to the query object foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, new Dictionary <string, object>()); var filterContext = new FilterContext { Query = contentQuery, State = FormParametersHelper.ToDynamic(tokenizedState) }; string category = filter.Category; string type = filter.Type; // look for the specific filter component var descriptor = availableFilters .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Filter(filterContext); contentQuery = filterContext.Query; } // iterate over each sort criteria to apply the alterations to the query object foreach (var sortCriterion in sortCriteria) { var sortCriterionContext = new SortCriterionContext { Query = contentQuery, State = FormParametersHelper.ToDynamic(sortCriterion.State) }; string category = sortCriterion.Category; string type = sortCriterion.Type; // look for the specific filter component var descriptor = availableSortCriteria .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); // ignore unfound descriptors if (descriptor == null) { continue; } // apply alteration descriptor.Sort(sortCriterionContext); contentQuery = sortCriterionContext.Query; } yield return(contentQuery); } }
private void ApplyCriterionForPart( SortCriterionContext context, SortCriterionConfiguration criterion) { var groupedMembers = GetMemberGroups(); var typeKey = groupedMembers.Keys // the type for the ContentPartRecord we asked .FirstOrDefault(k => k.FullName .Equals(criterion.PartRecordTypeName, StringComparison.OrdinalIgnoreCase)); if (typeKey == null) { // quality of life: allow to input only the class name rather than // the full name. e.g. TitlePartRecord rather than // Orchard.Core.Title.Models.TitlePartRecord var types = groupedMembers.Keys .Where(k => k.Name .Equals(criterion.PartRecordTypeName, StringComparison.OrdinalIgnoreCase)); if (types.Count() == 1) { typeKey = types.First(); } else if (types.Count() > 1) { var eMsg = T("The type asked for in the sort criterion does not have a unique name. Use its FullName.").Text + Environment.NewLine + T("The configuration is {0}.", criterion.PartRecordTypeName).Text + Environment.NewLine + T("Possible types found are: {0}", string.Join(Environment.NewLine, types.Select(t => t.FullName))).Text; Logger.Error(eMsg); } } if (typeKey != null) { var membersGroup = groupedMembers[typeKey]; var member = membersGroup // the property we asked .FirstOrDefault(m => m.Property.Name .Equals(criterion.PropertyName, StringComparison.OrdinalIgnoreCase)); if (member != null) { context.Query = criterion.Ascending ? context.Query .OrderBy(alias => alias.ContentPartRecord(typeKey), x => x.Asc(criterion.PropertyName)) : context.Query .OrderBy(alias => alias.ContentPartRecord(typeKey), x => x.Desc(criterion.PropertyName)); } else { Logger.Error( T("It was impossible to uniquely identify a property named {0} for type {1}. Perhaps it lacks a MemberBinding configuration?", criterion.PropertyName, criterion.PartRecordTypeName).Text); } } else { Logger.Error( T("It was impossible to uniquely identify a type for {0}. Perhaps it lacks a MemberBinding configuration?", criterion.PartRecordTypeName).Text); } if (criterion.Children.Any()) { foreach (var childCriterion in criterion.Children) { CriterionApplication(context, childCriterion); } } }
private void ApplyCriterionForField( SortCriterionContext context, SortCriterionConfiguration criterion) { // This uses the logic from ContentFieldsSortCriterion var partDefinition = _contentDefinitionManager.GetPartDefinition(criterion.PartName); if (partDefinition == null) { Logger.Error(T("Impossible to find a part definition with name {0}.", criterion.PartName).Text); } else { var fieldDefinition = partDefinition.Fields .FirstOrDefault(fd => fd.Name.Equals(criterion.FieldName)); if (fieldDefinition == null) { Logger.Error(T("Impossible to find a field definition with name {0} within the part {1}.", criterion.FieldName, criterion.PartName).Text); } else { var propertyName = string.Join(".", // part criterion.PartName, // field criterion.FieldName, // field's property (e.g. LinkField.Text) criterion.PropertyName ?? ""); var fieldTypeEditors = GetFieldEditors(fieldDefinition.FieldDefinition.Name, criterion.PropertyName); if (fieldTypeEditors.Any()) { // I think there should be only one foreach (var fieldTypeEditor in fieldTypeEditors) { // use an alias with the join so that two filters on the same Field Type wont collide var relationship = fieldTypeEditor.GetFilterRelationship(propertyName.ToSafeName()); // generate the predicate based on the editor which has been used Action <IHqlExpressionFactory> predicate = y => y.Eq("PropertyName", propertyName); // apply a filter for the specific property context.Query = context.Query.Where(relationship, predicate); // apply sort context.Query = criterion.Ascending ? context.Query.OrderBy(relationship, x => x.Asc(context.GetSortColumnName())) : context.Query.OrderBy(relationship, x => x.Desc(context.GetSortColumnName())); } } else { Logger.Error(T("Impossible to identify the IFieldTypeEditor to sort by {0}.", propertyName).Text); } } } if (criterion.Children.Any()) { foreach (var childCriterion in criterion.Children) { CriterionApplication(context, childCriterion); } } }
public LocalizedString DisplaySortCriterion(SortCriterionContext context, string sortName) { return(T("Ordered by {0}", sortName)); }
private LocalizedString Display(SortCriterionContext context, string name) { return(T(name)); }