mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-25 10:59:18 +08:00
ProjectionManager Extension (#7417)
- Defined a new interface IProjectionManagerExtension that inherits from IProjectionManager - ProjectionManager now implements IProjectionManagerExtension, so we can pass a part to GetCount and GetContentItems - GetCount and GetContentItems transform the part into a Content token, so you can filter data with informations contained in the Projection itself
This commit is contained in:
committed by
Sébastien Ros
parent
83f47ac148
commit
8a328902fd
@@ -24,7 +24,7 @@ using Orchard.Utility.Extensions;
|
||||
namespace Orchard.Projections.Drivers {
|
||||
public class ProjectionPartDriver : ContentPartDriver<ProjectionPart> {
|
||||
private readonly IRepository<QueryPartRecord> _queryRepository;
|
||||
private readonly IProjectionManager _projectionManager;
|
||||
private readonly IProjectionManagerExtension _projectionManager;
|
||||
private readonly IFeedManager _feedManager;
|
||||
private readonly ITokenizer _tokenizer;
|
||||
private readonly IDisplayHelperFactory _displayHelperFactory;
|
||||
@@ -34,7 +34,7 @@ namespace Orchard.Projections.Drivers {
|
||||
public ProjectionPartDriver(
|
||||
IOrchardServices services,
|
||||
IRepository<QueryPartRecord> queryRepository,
|
||||
IProjectionManager projectionManager,
|
||||
IProjectionManagerExtension projectionManager,
|
||||
IFeedManager feedManager,
|
||||
ITokenizer tokenizer,
|
||||
IDisplayHelperFactory displayHelperFactory,
|
||||
@@ -110,7 +110,7 @@ namespace Orchard.Projections.Drivers {
|
||||
_feedManager.Register(metaData.DisplayText, "rss", new RouteValueDictionary { { "projection", part.Id } });
|
||||
|
||||
// execute the query
|
||||
var contentItems = _projectionManager.GetContentItems(query.Id, pager.GetStartIndex() + part.Record.Skip, pager.PageSize).ToList();
|
||||
var contentItems = _projectionManager.GetContentItems(query.Id, part, pager.GetStartIndex() + part.Record.Skip, pager.PageSize).ToList();
|
||||
|
||||
// sanity check so that content items with ProjectionPart can't be added here, or it will result in an infinite loop
|
||||
contentItems = contentItems.Where(x => !x.Has<ProjectionPart>()).ToList();
|
||||
@@ -122,7 +122,7 @@ namespace Orchard.Projections.Drivers {
|
||||
|
||||
// create pager shape
|
||||
if (part.Record.DisplayPager) {
|
||||
var contentItemsCount = _projectionManager.GetCount(query.Id) - part.Record.Skip;
|
||||
var contentItemsCount = _projectionManager.GetCount(query.Id, part) - part.Record.Skip;
|
||||
contentItemsCount = Math.Max(0, contentItemsCount);
|
||||
pagerShape.TotalItemCount(contentItemsCount);
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
<Compile Include="Providers\Layouts\ShapeLayoutForms.cs" />
|
||||
<Compile Include="Providers\Properties\CustomValueProperties.cs" />
|
||||
<Compile Include="Navigation\NavigationQueryProvider.cs" />
|
||||
<Compile Include="Services\IProjectionManagerExtension.cs" />
|
||||
<Compile Include="Shapes.cs" />
|
||||
<Compile Include="Descriptors\Layout\LayoutComponentResult.cs" />
|
||||
<Compile Include="Descriptors\Layout\LayoutContext.cs" />
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Projections.Descriptors;
|
||||
using Orchard.Projections.Descriptors.Property;
|
||||
using Orchard.Projections.Descriptors.Filter;
|
||||
using Orchard.Projections.Descriptors.Layout;
|
||||
using Orchard.Projections.Descriptors.SortCriterion;
|
||||
|
||||
namespace Orchard.Projections.Services {
|
||||
public interface IProjectionManagerExtension : IProjectionManager {
|
||||
|
||||
IEnumerable<ContentItem> GetContentItems(int queryId, ContentPart part, int skip = 0, int count = 0);
|
||||
int GetCount(int queryId, ContentPart part);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ using Orchard.Projections.Models;
|
||||
using Orchard.Tokens;
|
||||
|
||||
namespace Orchard.Projections.Services {
|
||||
public class ProjectionManager : IProjectionManager{
|
||||
public class ProjectionManager : IProjectionManagerExtension {
|
||||
private readonly ITokenizer _tokenizer;
|
||||
private readonly IEnumerable<IFilterProvider> _filterProviders;
|
||||
private readonly IEnumerable<ISortCriterionProvider> _sortCriterionProviders;
|
||||
@@ -104,6 +104,33 @@ namespace Orchard.Projections.Services {
|
||||
}
|
||||
|
||||
public int GetCount(int queryId) {
|
||||
return GetCount(queryId, null);
|
||||
}
|
||||
|
||||
public int GetCount(int queryId, ContentPart part) {
|
||||
var queryRecord = _queryRepository.Get(queryId);
|
||||
|
||||
if (queryRecord == null) {
|
||||
throw new ArgumentException("queryId");
|
||||
}
|
||||
|
||||
// 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
|
||||
return GetContentQueries(queryRecord, Enumerable.Empty<SortCriterionRecord>(), tokens)
|
||||
.Sum(contentQuery => contentQuery.Count());
|
||||
}
|
||||
|
||||
public IEnumerable<ContentItem> GetContentItems(int queryId, int skip = 0, int count = 0) {
|
||||
return GetContentItems(queryId, null, skip, count);
|
||||
}
|
||||
|
||||
public IEnumerable<ContentItem> GetContentItems(int queryId, ContentPart part, int skip = 0, int count = 0) {
|
||||
var availableSortCriteria = DescribeSortCriteria().ToList();
|
||||
|
||||
var queryRecord = _queryRepository.Get(queryId);
|
||||
|
||||
@@ -111,36 +138,27 @@ namespace Orchard.Projections.Services {
|
||||
throw new ArgumentException("queryId");
|
||||
}
|
||||
|
||||
// aggregate the result for each group query
|
||||
|
||||
return GetContentQueries(queryRecord, Enumerable.Empty<SortCriterionRecord>())
|
||||
.Sum(contentQuery => contentQuery.Count());
|
||||
}
|
||||
|
||||
public IEnumerable<ContentItem> GetContentItems(int queryId, 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))) {
|
||||
foreach (var contentQuery in GetContentQueries(queryRecord, queryRecord.SortCriteria.OrderBy(sc => sc.Position), tokens)) {
|
||||
contentItems.AddRange(contentQuery.Slice(skip, count));
|
||||
}
|
||||
|
||||
if(queryRecord.FilterGroups.Count <= 1) {
|
||||
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) {
|
||||
if (ids.Length == 0) {
|
||||
return Enumerable.Empty<ContentItem>();
|
||||
}
|
||||
|
||||
@@ -173,9 +191,13 @@ namespace Orchard.Projections.Services {
|
||||
return groupQuery.Slice(skip, count);
|
||||
}
|
||||
|
||||
public IEnumerable<IHqlQuery> GetContentQueries(QueryPartRecord queryRecord, IEnumerable<SortCriterionRecord> sortCriteria) {
|
||||
public IEnumerable<IHqlQuery> GetContentQueries(QueryPartRecord queryRecord, IEnumerable<SortCriterionRecord> sortCriteria, Dictionary<string, object> tokens) {
|
||||
|
||||
var availableFilters = DescribeFilters().ToList();
|
||||
var availableSortCriteria = DescribeSortCriteria().ToList();
|
||||
if (tokens == null) {
|
||||
tokens = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
// pre-executing all groups
|
||||
foreach (var group in queryRecord.FilterGroups) {
|
||||
@@ -184,7 +206,7 @@ namespace Orchard.Projections.Services {
|
||||
|
||||
// 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 tokenizedState = _tokenizer.Replace(filter.State, tokens);
|
||||
var filterContext = new FilterContext {
|
||||
Query = contentQuery,
|
||||
State = FormParametersHelper.ToDynamic(tokenizedState)
|
||||
@@ -237,7 +259,7 @@ namespace Orchard.Projections.Services {
|
||||
|
||||
|
||||
yield return contentQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user