示例#1
0
        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));
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        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));
 }
示例#6
0
 private LocalizedString Display(SortCriterionContext context, string name)
 {
     return(T(name));
 }