-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDeletedContentItemDataTableDataProvider.cs
107 lines (96 loc) · 4.58 KB
/
DeletedContentItemDataTableDataProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using LinqToDB;
using Lombiq.DataTables.Constants;
using Lombiq.DataTables.Controllers;
using Lombiq.DataTables.Models;
using Lombiq.HelpfulLibraries.LinqToDb;
using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection;
using Microsoft.Extensions.Localization;
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement.Records;
using OrchardCore.Mvc.Core.Utilities;
using OrchardCore.Navigation;
using OrchardCore.Security.Permissions;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YesSql;
using static OrchardCore.Contents.CommonPermissions;
namespace Lombiq.DataTables.Services;
/// <summary>
/// This is a data provider which returns the list of deleted items with some <see cref="ContentItem"/> information.
/// </summary>
public class DeletedContentItemDataTableDataProvider : JsonResultDataTableDataProvider
{
private readonly ISession _session;
private readonly IStringLocalizer T;
public DeletedContentItemDataTableDataProvider(
IOrchardServices<DeletedContentItemDataTableDataProvider> orchardServices,
IDataTableDataProviderServices services)
: base(services, orchardServices.StringLocalizer.Value)
{
_session = orchardServices.Session.Value;
T = orchardServices.StringLocalizer.Value;
}
public override LocalizedString Description => T["Deleted Content Items"];
public override IEnumerable<Permission> AllowedPermissions => [DeleteContent];
protected override async Task<JsonResultDataTableDataProviderResult> GetResultsAsync(DataTableDataRequest request) =>
new(await GetDeletedContentItemIndicesAsync(_session, request.QueryId));
protected override DataTableColumnsDefinition GetColumnsDefinitionInner(string queryId) =>
this.DefineColumns(
nameof(ContentItemIndex.Id),
SortingDirection.Descending,
(nameof(ContentItemIndex.Id), T["ID"]),
(nameof(ContentItemIndex.ContentItemId), T["Content Item ID"]),
(nameof(ContentItemIndex.ContentItemVersionId), T["Content Item Version ID"]),
(nameof(ContentItemIndex.DisplayText), T["Title"]),
(nameof(ContentItemIndex.Author), T["Author"]),
(nameof(ContentItemIndex.Owner), T["Owner"]),
(nameof(ContentItemIndex.CreatedUtc), T["Created Date"]),
(nameof(ContentItemIndex.ModifiedUtc), T["Modified Date"]),
(nameof(ContentItemIndex.PublishedUtc), T["Deleted Date"]));
public static NavigationItemBuilder AddMenuItem(
NavigationItemBuilder builder,
string queryId) =>
builder
.AddClass("deletedContent" + queryId)
.Action(
nameof(TableController.Get),
typeof(TableController).ControllerName(),
new
{
area = FeatureIds.Area,
providerName = nameof(DeletedContentItemDataTableDataProvider),
queryId,
})
.Permission(DeleteContent)
.LocalNav();
/// <summary>
/// Returns the list of each deleted <see cref="ContentItem"/>'s index for the specified content type.
/// </summary>
public static async Task<IEnumerable<ContentItemIndex>> GetDeletedContentItemIndicesAsync(
ISession session,
string contentType)
{
// This returns the indices which don't have a published or draft content item version. Still needs to be
// grouped offline to only select the latest one.
Task<ContentItemIndex[]> SqlQuery(ITableAccessor accessor) =>
(from deleted in accessor.GetTable<ContentItemIndex>()
from notDeleted in
(from contentItemIndex in accessor.GetTable<ContentItemIndex>()
where contentItemIndex.ContentType == contentType
&& (contentItemIndex.Latest || contentItemIndex.Published)
group contentItemIndex by contentItemIndex.ContentItemId into contentItemIdGroup
select contentItemIdGroup.Key)
.LeftJoin(notDeleted => notDeleted == deleted.ContentItemId)
where deleted.ContentType == contentType && notDeleted == null
select deleted)
.ToArrayAsync();
var result = await session.LinqQueryAsync(SqlQuery);
return result
.GroupBy(index => index.ContentItemId)
.Select(group => group
.OrderBy(index => string.IsNullOrWhiteSpace(index.DisplayText) ? 1 : 0)
.ThenByDescending(index => index.PublishedUtc)
.First());
}
}