diff --git a/src/Orchard.Web/Modules/Orchard.Projections/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Projections/Controllers/AdminController.cs index 01b79f29d2e..eb9dfc7943a 100644 --- a/src/Orchard.Web/Modules/Orchard.Projections/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Projections/Controllers/AdminController.cs @@ -1,9 +1,13 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Web.Routing; +using Orchard.ContentManagement; using Orchard.Core.Title.Models; +using Orchard.DisplayManagement; using Orchard.Forms.Services; +using Orchard.Localization; using Orchard.Mvc; using Orchard.Projections.Descriptors.Filter; using Orchard.Projections.Descriptors.Layout; @@ -11,13 +15,9 @@ using Orchard.Projections.Models; using Orchard.Projections.Services; using Orchard.Projections.ViewModels; -using Orchard.ContentManagement; -using Orchard.DisplayManagement; -using Orchard.Localization; -using Orchard.UI.Notify; -using System; using Orchard.Settings; using Orchard.UI.Navigation; +using Orchard.UI.Notify; namespace Orchard.Projections.Controllers { [ValidateInput(false)] @@ -84,7 +84,7 @@ public ActionResult Index(AdminIndexOptions options, PagerParameters pagerParame var model = new AdminIndexViewModel { Queries = results.Select(x => new QueryEntry { - Query = x.As().Record, + Query = x.As().Record, QueryId = x.Id, Name = x.As().Name }).ToList(), @@ -158,16 +158,21 @@ public ActionResult Edit(int id) { Category = f.Category, Type = f.Type, FilterRecordId = filter.Id, - DisplayText = String.IsNullOrWhiteSpace(filter.Description) ? f.Display(new FilterContext {State = FormParametersHelper.ToDynamic(filter.State)}).Text : filter.Description + DisplayText = String.IsNullOrWhiteSpace(filter.Description) ? f.Display(new FilterContext { State = FormParametersHelper.ToDynamic(filter.State) }).Text : filter.Description }); } } - filterGroupEntries.Add( new FilterGroupEntry { Id = group.Id, Filters = filterEntries } ); + filterGroupEntries.Add(new FilterGroupEntry { Id = group.Id, Filters = filterEntries }); } viewModel.FilterGroups = filterGroupEntries; + if (viewModel.FilterGroups.Any(group => group.Filters.Count() == 0)) { + _services.Notifier.Warning( + T("This Query has at least one empty filter group, which will cause all content items to be returned, unless the Projection using this Query limits the number of content items displayed.")); + } + #endregion #region Load Sort criterias @@ -185,7 +190,7 @@ public ActionResult Edit(int id) { Category = f.Category, Type = f.Type, SortCriterionRecordId = sortCriterion.Id, - DisplayText = String.IsNullOrWhiteSpace(sortCriterion.Description) ? f.Display(new SortCriterionContext { State = FormParametersHelper.ToDynamic(sortCriterion.State) }).Text : sortCriterion.Description + DisplayText = String.IsNullOrWhiteSpace(sortCriterion.Description) ? f.Display(new SortCriterionContext { State = FormParametersHelper.ToDynamic(sortCriterion.State) }).Text : sortCriterion.Description }); } } diff --git a/src/Orchard.Web/Modules/Orchard.Projections/Drivers/ProjectionPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Projections/Drivers/ProjectionPartDriver.cs index 352368fe60c..7230ac7c3ae 100644 --- a/src/Orchard.Web/Modules/Orchard.Projections/Drivers/ProjectionPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Projections/Drivers/ProjectionPartDriver.cs @@ -20,10 +20,12 @@ using Orchard.Projections.ViewModels; using Orchard.Tokens; using Orchard.UI.Navigation; +using Orchard.UI.Notify; using Orchard.Utility.Extensions; namespace Orchard.Projections.Drivers { public class ProjectionPartDriver : ContentPartDriver { + private readonly IOrchardServices _orchardServices; private readonly IRepository _queryRepository; private readonly IProjectionManagerExtension _projectionManager; private readonly IFeedManager _feedManager; @@ -33,25 +35,25 @@ public class ProjectionPartDriver : ContentPartDriver { private const string TemplateName = "Parts/ProjectionPart"; public ProjectionPartDriver( - IOrchardServices services, + IOrchardServices orchardServices, IRepository queryRepository, IProjectionManagerExtension projectionManager, IFeedManager feedManager, ITokenizer tokenizer, IDisplayHelperFactory displayHelperFactory, IWorkContextAccessor workContextAccessor) { + _orchardServices = orchardServices; _queryRepository = queryRepository; _projectionManager = projectionManager; _feedManager = feedManager; _tokenizer = tokenizer; _displayHelperFactory = displayHelperFactory; _workContextAccessor = workContextAccessor; + T = NullLocalizer.Instance; - Services = services; } public Localizer T { get; set; } - public IOrchardServices Services { get; set; } protected override string Prefix { get { return "ProjectionPart"; } } @@ -59,7 +61,7 @@ protected override DriverResult Display(ProjectionPart part, string displayType, var query = part.Record.QueryPartRecord; // retrieving paging parameters - var queryString = Services.WorkContext.HttpContext.Request.QueryString; + var queryString = _orchardServices.WorkContext.HttpContext.Request.QueryString; var pageKey = String.IsNullOrWhiteSpace(part.Record.PagerSuffix) ? "page" : "page-" + part.Record.PagerSuffix; var page = 0; @@ -81,16 +83,14 @@ protected override DriverResult Display(ProjectionPart part, string displayType, var pageSizeKey = "pageSize" + part.Record.PagerSuffix; if (queryString.AllKeys.Contains(pageSizeKey)) { - int qsPageSize; - - if (Int32.TryParse(queryString[pageSizeKey], out qsPageSize)) { + if (Int32.TryParse(queryString[pageSizeKey], out int qsPageSize)) { if (part.Record.MaxItems == 0 || qsPageSize <= part.Record.MaxItems) { pageSize = qsPageSize; } } } - var pager = new Pager(Services.WorkContext.CurrentSite, page, pageSize); + var pager = new Pager(_orchardServices.WorkContext.CurrentSite, page, pageSize); var pagerShape = shapeHelper.Pager(pager) .ContentPart(part) @@ -107,7 +107,7 @@ protected override DriverResult Display(ProjectionPart part, string displayType, ContentShape("Parts_ProjectionPart_List", shape => { // generates a link to the RSS feed for this term - var metaData = Services.ContentManager.GetItemMetadata(part.ContentItem); + var metaData = _orchardServices.ContentManager.GetItemMetadata(part.ContentItem); _feedManager.Register(metaData.DisplayText, "rss", new RouteValueDictionary { { "projection", part.Id } }); // execute the query @@ -130,8 +130,8 @@ protected override DriverResult Display(ProjectionPart part, string displayType, // renders in a standard List shape if no specific layout could be found if (layoutDescriptor == null) { - var list = Services.New.List(); - var contentShapes = contentItems.Select(item => Services.ContentManager.BuildDisplay(item, "Summary")); + var list = _orchardServices.New.List(); + var contentShapes = contentItems.Select(item => _orchardServices.ContentManager.BuildDisplay(item, "Summary")); list.AddRange(contentShapes); return list; @@ -143,7 +143,7 @@ protected override DriverResult Display(ProjectionPart part, string displayType, var layoutComponents = contentItems.Select( contentItem => { - var contentItemMetadata = Services.ContentManager.GetItemMetadata(contentItem); + var contentItemMetadata = _orchardServices.ContentManager.GetItemMetadata(contentItem); var propertyDescriptors = fieldDescriptors.Select( d => { @@ -156,9 +156,9 @@ protected override DriverResult Display(ProjectionPart part, string displayType, }); // apply all settings to the field content, wrapping it in a FieldWrapper shape - var properties = Services.New.Properties( + var properties = _orchardServices.New.Properties( Items: propertyDescriptors.Select( - pd => Services.New.PropertyWrapper( + pd => _orchardServices.New.PropertyWrapper( Item: pd.Shape, Property: pd.Property, ContentItem: contentItem, @@ -199,14 +199,14 @@ protected override DriverResult Display(ProjectionPart part, string displayType, return key; }).Select(x => new { Key = x.Key, Components = x }); - var list = Services.New.List(); + var list = _orchardServices.New.List(); foreach (var group in groups) { var localResult = layoutDescriptor.Render(renderLayoutContext, group.Components); // add the Context to the shape localResult.Context(renderLayoutContext); - list.Add(Services.New.LayoutGroup(Key: new MvcHtmlString(group.Key), List: localResult)); + list.Add(_orchardServices.New.LayoutGroup(Key: new MvcHtmlString(group.Key), List: localResult)); } return list; @@ -223,81 +223,80 @@ protected override DriverResult Display(ProjectionPart part, string displayType, } protected override DriverResult Editor(ProjectionPart part, dynamic shapeHelper) { - return ContentShape("Parts_ProjectionPart_Edit", - () => { - var model = new ProjectionPartEditViewModel(); - - // for create read the setting values - var settings = part.TypePartDefinition.Settings.GetModel(); - if (part.Id == 0) { - model = new ProjectionPartEditViewModel { - DisplayPager = settings.DisplayPager, - Items = settings.Items, - Skip = settings.Skip, - PagerSuffix = settings.PagerSuffix, - MaxItems = settings.MaxItems, - QueryLayoutRecordId = settings.QueryLayoutRecordId - }; - } - else { - model = new ProjectionPartEditViewModel { - DisplayPager = part.Record.DisplayPager, - Items = part.Record.Items, - ItemsPerPage = part.Record.ItemsPerPage, - Skip = part.Record.Skip, - PagerSuffix = part.Record.PagerSuffix, - MaxItems = part.Record.MaxItems, - QueryLayoutRecordId = "-1" - }; - // concatenated Query and Layout ids for the view - if (part.Record.QueryPartRecord != null) { - model.QueryLayoutRecordId = part.Record.QueryPartRecord.Id + ";"; - } - - if (part.Record.LayoutRecord != null) { - model.QueryLayoutRecordId += part.Record.LayoutRecord.Id.ToString(); - } - else { - model.QueryLayoutRecordId += "-1"; - } - } - - model.PartId = part.Id; - - // lock fields - model.LockEditingItems = settings.LockEditingItems; - model.LockEditingSkip = settings.LockEditingSkip; - model.LockEditingMaxItems = settings.LockEditingMaxItems; - model.LockEditingPagerSuffix = settings.LockEditingPagerSuffix; - model.LockEditingDisplayPager = settings.LockEditingDisplayPager; - - // populating the list of queries and layouts - var layouts = _projectionManager.DescribeLayouts().SelectMany(x => x.Descriptors).ToList(); - model.QueryRecordEntries = Services.ContentManager.Query().Join().OrderBy(x => x.Title).List() - .Select(x => new QueryRecordEntry { - Id = x.Id, - Name = x.Name, - LayoutRecordEntries = x.Layouts.Select(l => new LayoutRecordEntry { - Id = l.Id, - Description = GetLayoutDescription(layouts, l) - }) - }); - - // if any values, use default list of the settings - if (!string.IsNullOrWhiteSpace(settings.FilterQueryRecordId)) { - var filterQueryRecordId = settings.FilterQueryRecordId.Split('&'); - model.QueryRecordIdFilterEntries = filterQueryRecordId - .Select(x => new QueryRecordFilterEntry { - Id = x.Split(';')[0], - LayoutId = x.Split(';')[1] - }); - } - else { - model.QueryRecordIdFilterEntries = new List(); - } - - return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix); - }); + return ContentShape("Parts_ProjectionPart_Edit", () => { + var model = new ProjectionPartEditViewModel(); + + // for create read the setting values + var settings = part.TypePartDefinition.Settings.GetModel(); + if (part.Id == 0) { + model = new ProjectionPartEditViewModel { + DisplayPager = settings.DisplayPager, + Items = settings.Items, + Skip = settings.Skip, + PagerSuffix = settings.PagerSuffix, + MaxItems = settings.MaxItems, + QueryLayoutRecordId = settings.QueryLayoutRecordId + }; + } + else { + model = new ProjectionPartEditViewModel { + DisplayPager = part.Record.DisplayPager, + Items = part.Record.Items, + ItemsPerPage = part.Record.ItemsPerPage, + Skip = part.Record.Skip, + PagerSuffix = part.Record.PagerSuffix, + MaxItems = part.Record.MaxItems, + QueryLayoutRecordId = "-1" + }; + // concatenated Query and Layout ids for the view + if (part.Record.QueryPartRecord != null) { + model.QueryLayoutRecordId = part.Record.QueryPartRecord.Id + ";"; + } + + if (part.Record.LayoutRecord != null) { + model.QueryLayoutRecordId += part.Record.LayoutRecord.Id.ToString(); + } + else { + model.QueryLayoutRecordId += "-1"; + } + } + + model.PartId = part.Id; + + // lock fields + model.LockEditingItems = settings.LockEditingItems; + model.LockEditingSkip = settings.LockEditingSkip; + model.LockEditingMaxItems = settings.LockEditingMaxItems; + model.LockEditingPagerSuffix = settings.LockEditingPagerSuffix; + model.LockEditingDisplayPager = settings.LockEditingDisplayPager; + + // populating the list of queries and layouts + var layouts = _projectionManager.DescribeLayouts().SelectMany(x => x.Descriptors).ToList(); + model.QueryRecordEntries = _orchardServices.ContentManager.Query().Join().OrderBy(x => x.Title).List() + .Select(x => new QueryRecordEntry { + Id = x.Id, + Name = x.Name, + LayoutRecordEntries = x.Layouts.Select(l => new LayoutRecordEntry { + Id = l.Id, + Description = GetLayoutDescription(layouts, l) + }) + }); + + // if any values, use default list of the settings + if (!string.IsNullOrWhiteSpace(settings.FilterQueryRecordId)) { + var filterQueryRecordId = settings.FilterQueryRecordId.Split('&'); + model.QueryRecordIdFilterEntries = filterQueryRecordId + .Select(x => new QueryRecordFilterEntry { + Id = x.Split(';')[0], + LayoutId = x.Split(';')[1] + }); + } + else { + model.QueryRecordIdFilterEntries = new List(); + } + + return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix); + }); } private static string GetLayoutDescription(IEnumerable layouts, LayoutRecord l) { @@ -313,7 +312,7 @@ protected override DriverResult Editor(ProjectionPart part, IUpdateModel updater updater.TryUpdateModel(model, Prefix, null, null); model.PartId = part.Id; - + // check the setting, if it is unlocked, assign the setting value if (settings.LockEditingDisplayPager) { part.Record.DisplayPager = settings.DisplayPager; @@ -356,6 +355,12 @@ protected override DriverResult Editor(ProjectionPart part, IUpdateModel updater updater.AddModelError("PagerSuffix", T("Suffix should not contain special characters.")); } + if (model.Items == 0 + && (part.Record.QueryPartRecord?.FilterGroups.Any(group => group.Filters.Count == 0) ?? false)) { + _orchardServices.Notifier.Warning( + T("The selected Query has at least one empty filter group, which causes all content items to be returned. It is recommended to limit the number of content items queried by setting the 'Items to display' field to a non-zero value.")); + } + return Editor(part, shapeHelper); } @@ -376,12 +381,11 @@ protected override void Importing(ProjectionPart part, ImportContentContext cont protected override void ImportCompleted(ProjectionPart part, ImportContentContext context) { // Assign the query only when everything is imported. var query = context.Attribute(part.PartDefinition.Name, "Query"); - if (query != null && context.GetItemFromSession(query).As()!=null) { + if (query != null && context.GetItemFromSession(query).As() != null) { part.Record.QueryPartRecord = context.GetItemFromSession(query).As().Record; var layoutIndex = context.Attribute(part.PartDefinition.Name, "LayoutIndex"); - int layoutIndexValue; if (layoutIndex != null - && Int32.TryParse(layoutIndex, out layoutIndexValue) + && Int32.TryParse(layoutIndex, out int layoutIndexValue) && layoutIndexValue >= 0 && part.Record.QueryPartRecord.Layouts.Count > layoutIndexValue) { part.Record.LayoutRecord = part.Record.QueryPartRecord.Layouts[Int32.Parse(layoutIndex)]; @@ -398,9 +402,9 @@ protected override void Exporting(ProjectionPart part, ExportContentContext cont context.Element(part.PartDefinition.Name).SetAttributeValue("DisplayPager", part.Record.DisplayPager); if (part.Record.QueryPartRecord != null) { - var queryPart = Services.ContentManager.Query("Query").Where(x => x.Id == part.Record.QueryPartRecord.Id).List().FirstOrDefault(); + var queryPart = _orchardServices.ContentManager.Query("Query").Where(x => x.Id == part.Record.QueryPartRecord.Id).List().FirstOrDefault(); if (queryPart != null) { - var queryIdentity = Services.ContentManager.GetItemMetadata(queryPart).Identity; + var queryIdentity = _orchardServices.ContentManager.GetItemMetadata(queryPart).Identity; context.Element(part.PartDefinition.Name).SetAttributeValue("Query", queryIdentity.ToString()); context.Element(part.PartDefinition.Name).SetAttributeValue("LayoutIndex", part.Record.QueryPartRecord.Layouts.IndexOf(part.Record.LayoutRecord)); } diff --git a/src/Orchard.Web/Modules/Orchard.Projections/Drivers/QueryPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Projections/Drivers/QueryPartDriver.cs index f737ee6cc3c..8024f7704be 100644 --- a/src/Orchard.Web/Modules/Orchard.Projections/Drivers/QueryPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Projections/Drivers/QueryPartDriver.cs @@ -19,14 +19,16 @@ public QueryPartDriver(IProjectionManager projectionManager, IFormManager formMa _projectionManager = projectionManager; _formManager = formManager; } + protected override string Prefix { get { return "Query_Part"; } } - protected override DriverResult Editor(QueryPart part, dynamic shapeHelper) { - return Editor(part, null, shapeHelper); - } + + protected override DriverResult Editor(QueryPart part, dynamic shapeHelper) => + Editor(part, null, shapeHelper); + protected override DriverResult Editor(QueryPart part, IUpdateModel updater, dynamic shapeHelper) { var model = new QueryViewModel { VersionScope = part.VersionScope }; if (updater != null) { @@ -34,10 +36,10 @@ protected override DriverResult Editor(QueryPart part, IUpdateModel updater, dyn part.VersionScope = model.VersionScope; } } - return ContentShape("Parts_QueryPart_Edit", - () => { - return shapeHelper.EditorTemplate(TemplateName: "Parts/QueryPart_Edit", Model: model, Prefix: Prefix); - }); + + return ContentShape("Parts_QueryPart_Edit", () => { + return shapeHelper.EditorTemplate(TemplateName: "Parts/QueryPart_Edit", Model: model, Prefix: Prefix); + }); } protected override void Exporting(QueryPart part, ExportContentContext context) { @@ -60,12 +62,12 @@ protected override void Exporting(QueryPart part, ExportContentContext context) } return new XElement("Filter", - new XAttribute("Category", filter.Category ?? ""), - new XAttribute("Description", filter.Description ?? ""), - new XAttribute("Position", filter.Position), - new XAttribute("State", state ?? ""), - new XAttribute("Type", filter.Type ?? "") - ); + new XAttribute("Category", filter.Category ?? ""), + new XAttribute("Description", filter.Description ?? ""), + new XAttribute("Position", filter.Position), + new XAttribute("State", state ?? ""), + new XAttribute("Type", filter.Type ?? "") + ); }) ) ) diff --git a/src/Orchard.Web/Modules/Orchard.Projections/Services/ProjectionManager.cs b/src/Orchard.Web/Modules/Orchard.Projections/Services/ProjectionManager.cs index 6a1a0368ee2..1fe8f964b5a 100644 --- a/src/Orchard.Web/Modules/Orchard.Projections/Services/ProjectionManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Projections/Services/ProjectionManager.cs @@ -108,19 +108,15 @@ public int GetCount(int queryId) { } public int GetCount(int queryId, ContentPart part) { - var queryRecord = _queryRepository.Get(queryId); - - if (queryRecord == null) { - throw new ArgumentException("queryId"); - } + var queryRecord = _queryRepository.Get(queryId) ?? throw new ArgumentException("queryId"); - // prepares tokens + // Prepare tokens. Dictionary tokens = new Dictionary(); if (part != null) { tokens.Add("Content", part.ContentItem); } - // aggregate the result for each group query + // Aggregate the result of each filter group. return GetContentQueries(queryRecord, Enumerable.Empty(), tokens) .Sum(contentQuery => contentQuery.Count()); } @@ -140,13 +136,13 @@ public IEnumerable GetContentItems(int queryId, ContentPart part, i var contentItems = new List(); - // prepares tokens + // Prepare tokens. Dictionary tokens = new Dictionary(); if (part != null) { tokens.Add("Content", part.ContentItem); } - // aggregate the result for each group query + // Aggregate the result of each filter group. foreach (var contentQuery in GetContentQueries(queryRecord, queryRecord.SortCriteria.OrderBy(sc => sc.Position), tokens)) { contentItems.AddRange(contentQuery.Slice(skip, count)); } @@ -155,7 +151,7 @@ public IEnumerable GetContentItems(int queryId, ContentPart part, i return contentItems; } - // re-executing the sorting with the cumulated groups + // Re-executing the sorting on the aggregated results. var ids = contentItems.Select(c => c.Id).ToArray(); if (ids.Length == 0) { @@ -164,7 +160,7 @@ public IEnumerable GetContentItems(int queryId, ContentPart part, i 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 + // Iterate over each sort criteria to apply the alterations to the query object. foreach (var sortCriterion in queryRecord.SortCriteria.OrderBy(s => s.Position)) { var tokenizedState = _tokenizer.Replace(sortCriterion.State, tokens); var sortCriterionContext = new SortCriterionContext { @@ -177,15 +173,17 @@ public IEnumerable GetContentItems(int queryId, ContentPart part, i 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); + // Find specific sort criterion. + var descriptor = availableSortCriteria + .SelectMany(x => x.Descriptors) + .FirstOrDefault(x => x.Category == category && x.Type == type); - // ignore unfound descriptors + // Skip if not found. if (descriptor == null) { continue; } - // apply alteration + // Apply alteration. descriptor.Sort(sortCriterionContext); groupQuery = sortCriterionContext.Query; @@ -194,7 +192,10 @@ public IEnumerable GetContentItems(int queryId, ContentPart part, i return groupQuery.Slice(skip, count); } - public IEnumerable GetContentQueries(QueryPartRecord queryRecord, IEnumerable sortCriteria, Dictionary tokens) { + public IEnumerable GetContentQueries( + QueryPartRecord queryRecord, + IEnumerable sortCriteria, + Dictionary tokens) { var availableFilters = DescribeFilters().ToList(); var availableSortCriteria = DescribeSortCriteria().ToList(); @@ -204,11 +205,11 @@ public IEnumerable GetContentQueries(QueryPartRecord queryRecord, IEn var version = queryRecord.VersionScope.ToVersionOptions(); - // pre-executing all groups + // Iterate over each filter group and evaluate the filters. foreach (var group in queryRecord.FilterGroups) { var contentQuery = _contentManager.HqlQuery().ForVersion(version); - // iterate over each filter to apply the alterations to the query object + // Iterate over each filter to apply the alterations to the query object. foreach (var filter in group.Filters) { var tokenizedState = _tokenizer.Replace(filter.State, tokens); var filterContext = new FilterContext { @@ -221,23 +222,23 @@ public IEnumerable GetContentQueries(QueryPartRecord queryRecord, IEn string category = filter.Category; string type = filter.Type; - // look for the specific filter component + // Find specific filter. var descriptor = availableFilters .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); - // ignore unfound descriptors + // Skip if not found. if (descriptor == null) { continue; } - // apply alteration + // Apply alteration. descriptor.Filter(filterContext); contentQuery = filterContext.Query; } - // iterate over each sort criteria to apply the alterations to the query object + // Iterate over each sort criteria to apply the alterations to the query object. foreach (var sortCriterion in sortCriteria.OrderBy(s => s.Position)) { var tokenizedState = _tokenizer.Replace(sortCriterion.State, tokens); var sortCriterionContext = new SortCriterionContext { @@ -250,23 +251,22 @@ public IEnumerable GetContentQueries(QueryPartRecord queryRecord, IEn string category = sortCriterion.Category; string type = sortCriterion.Type; - // look for the specific filter component + // Find specific sort criterion. var descriptor = availableSortCriteria .SelectMany(x => x.Descriptors) .FirstOrDefault(x => x.Category == category && x.Type == type); - // ignore unfound descriptors + // Skip if not found. if (descriptor == null) { continue; } - // apply alteration + // Apply alteration. descriptor.Sort(sortCriterionContext); contentQuery = sortCriterionContext.Query; } - yield return contentQuery; } }