More robust handling of audit trail event records whose providers are no longer enabled.

This commit is contained in:
Sipke Schoorstra
2014-07-31 20:56:46 -07:00
parent 81514eeb2d
commit 84c651a0eb
16 changed files with 48 additions and 16 deletions

View File

@@ -52,8 +52,7 @@ namespace Orchard.AuditTrail.Controllers {
var eventDescriptors = eventDescriptorsQuery.ToDictionary(x => x.Event);
var recordViewModelsQuery =
from record in pageOfData
let descriptor = eventDescriptors.ContainsKey(record.FullEventName) ? eventDescriptors[record.FullEventName] : default(AuditTrailEventDescriptor)
where descriptor != null
let descriptor = eventDescriptors.ContainsKey(record.FullEventName) ? eventDescriptors[record.FullEventName] : AuditTrailEventDescriptor.Basic(record)
select new AuditTrailEventSummaryViewModel {
Record = record,
EventDescriptor = descriptor,
@@ -76,7 +75,7 @@ namespace Orchard.AuditTrail.Controllers {
return new HttpUnauthorizedResult();
var record = _auditTrailManager.GetRecord(id);
var descriptor = _auditTrailManager.DescribeEvent(record.FullEventName);
var descriptor = _auditTrailManager.DescribeEvent(record);
var detailsShape = _displayBuilder.BuildDisplay(record, "Detail");
var viewModel = new AuditTrailDetailsViewModel {
Record = record,

View File

@@ -3,8 +3,10 @@ using Orchard.AuditTrail.Helpers;
using Orchard.AuditTrail.Shapes;
using Orchard.ContentManagement.MetaData.Services;
using Orchard.DisplayManagement.Implementation;
using Orchard.Environment.Extensions;
namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes {
[OrchardFeature("Orchard.AuditTrail.ContentDefinition")]
public class ContentPartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration<ContentPartAuditTrailEventProvider> {
private readonly ISettingsFormatter _settingsFormatter;
public ContentPartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) {

View File

@@ -4,8 +4,10 @@ using Orchard.AuditTrail.Shapes;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.MetaData.Services;
using Orchard.DisplayManagement.Implementation;
using Orchard.Environment.Extensions;
namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes {
[OrchardFeature("Orchard.AuditTrail.ContentDefinition")]
public class ContentTypeFieldSettingsUpdatedEventShape : AuditTrailEventShapeAlteration<ContentPartAuditTrailEventProvider> {
private readonly ISettingsFormatter _settingsFormatter;
public ContentTypeFieldSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) {

View File

@@ -3,8 +3,10 @@ using Orchard.AuditTrail.Helpers;
using Orchard.AuditTrail.Shapes;
using Orchard.ContentManagement.MetaData.Services;
using Orchard.DisplayManagement.Implementation;
using Orchard.Environment.Extensions;
namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes {
[OrchardFeature("Orchard.AuditTrail.ContentDefinition")]
public class ContentTypePartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration<ContentTypeAuditTrailEventProvider> {
private readonly ISettingsFormatter _settingsFormatter;
public ContentTypePartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) {

View File

@@ -3,8 +3,10 @@ using Orchard.AuditTrail.Helpers;
using Orchard.AuditTrail.Shapes;
using Orchard.ContentManagement.MetaData.Services;
using Orchard.DisplayManagement.Implementation;
using Orchard.Environment.Extensions;
namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes {
[OrchardFeature("Orchard.AuditTrail.ContentDefinition")]
public class ContentTypeSettingsUpdatedEventShape : AuditTrailEventShapeAlteration<ContentTypeAuditTrailEventProvider> {
private readonly ISettingsFormatter _settingsFormatter;
public ContentTypeSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) {

View File

@@ -18,7 +18,7 @@ namespace Orchard.AuditTrail.Services {
public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) {
var eventData = _serializer.Deserialize(record.EventData);
var descriptor = _auditTrailManager.DescribeEvent(record.FullEventName);
var descriptor = _auditTrailManager.DescribeEvent(record);
var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData, Descriptor: descriptor);
var metaData = (ShapeMetadata)auditTrailEventShape.Metadata;
metaData.DisplayType = displayType;

View File

@@ -184,6 +184,10 @@ namespace Orchard.AuditTrail.Services {
return context;
}
public AuditTrailEventDescriptor DescribeEvent(AuditTrailEventRecord record) {
return DescribeEvent(record.FullEventName) ?? AuditTrailEventDescriptor.Basic(record);
}
public AuditTrailEventDescriptor DescribeEvent<T>(string eventName) where T : IAuditTrailEventProvider {
var fullyQualifiedEventName = EventNameExtensions.GetFullyQualifiedEventName<T>(eventName);
return DescribeEvent(fullyQualifiedEventName);
@@ -198,11 +202,7 @@ namespace Orchard.AuditTrail.Services {
select e;
var eventDescriptors = eventDescriptorQuery.ToArray();
if (!eventDescriptors.Any()) {
throw new ArgumentException(String.Format("No event named '{0}' exists.", fullyQualifiedEventName), "fullyQualifiedEventName");
}
return eventDescriptors.First();
return eventDescriptors.FirstOrDefault();
}
public IEnumerable<AuditTrailEventRecord> Trim(TimeSpan retentionPeriod) {

View File

@@ -55,6 +55,13 @@ namespace Orchard.AuditTrail.Services {
/// </summary>
DescribeContext DescribeProviders();
/// <summary>
/// Describes a single audit trail event.
/// </summary>
/// <param name="record">The audit trail event record for which to find its descriptor.</param>
/// <returns>A single audit trail event descriptor.</returns>
AuditTrailEventDescriptor DescribeEvent(AuditTrailEventRecord record);
/// <summary>
/// Describes a single audit trail event.
/// </summary>

View File

@@ -1,3 +1,5 @@
using System.Linq;
using Orchard.AuditTrail.Models;
using Orchard.Localization;
namespace Orchard.AuditTrail.Services.Models {
@@ -8,5 +10,21 @@ namespace Orchard.AuditTrail.Services.Models {
public LocalizedString Description { get; set; }
public bool IsEnabledByDefault { get; set; }
public bool IsMandatory { get; set; }
/// <summary>
/// Returns a basic descriptor based on an event record.
/// This is useful in cases where event records were previously stored by providers that are no longer enabled.
/// </summary>
public static AuditTrailEventDescriptor Basic(AuditTrailEventRecord record) {
return new AuditTrailEventDescriptor {
CategoryDescriptor = new AuditTrailCategoryDescriptor {
Category = record.Category,
Events = Enumerable.Empty<AuditTrailEventDescriptor>(),
Name = new LocalizedString(record.Category)
},
Event = record.EventName,
Name = new LocalizedString(record.EventName)
};
}
}
}

View File

@@ -9,7 +9,7 @@
var contentFieldName = eventData.Get<string>("ContentFieldName");
var oldDisplayName = (string)Model.OldDisplayName;
var newDisplayName = (string)Model.NewDisplayName;
var diff = (DiffDictionary<string, string>)Model.Diff;
var diff = (DiffDictionary<string, string>)Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contentpart-eventsummary">
@T("Settings for the field <strong>{0}</strong> attached to the {1} content part were updated:", contentFieldName, Html.ContentPartEditLink(contentPartName))

View File

@@ -9,7 +9,7 @@
var contentFieldName = eventData.Get<string>("ContentFieldName");
var oldDisplayName = (string)Model.OldDisplayName;
var newDisplayName = (string)Model.NewDisplayName;
var diff = (DiffDictionary<string, string>)Model.Diff;
var diff = (DiffDictionary<string, string>)Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contentpart-eventsummary">
@T("Settings for the field <strong>{0}</strong> attached to the {1} content part were updated:", contentFieldName, Html.ContentPartEditLink(contentPartName))

View File

@@ -6,7 +6,7 @@
@{
var eventData = (IDictionary<string, object>)Model.EventData;
var contentPartName = eventData.Get<string>("ContentPartName");
var diff = (DiffDictionary<string, string>)Model.Diff;
var diff = (DiffDictionary<string, string>)Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contentpart-eventsummary">
@T("Settings for the content part {0} were changed:", Html.ContentPartEditLink(contentPartName))

View File

@@ -6,7 +6,7 @@
@{
var eventData = (IDictionary<string, object>)Model.EventData;
var contentPartName = eventData.Get<string>("ContentPartName");
var diff = (DiffDictionary<string, string>)Model.Diff;
var diff = (DiffDictionary<string, string>)Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contentpart-eventsummary">
@T("Settings for the content part {0} were changed:", Html.ContentPartEditLink(contentPartName))

View File

@@ -7,7 +7,7 @@
var eventData = (IDictionary<string, object>) Model.EventData;
var contentTypeName = eventData.Get<string>("ContentTypeName");
var contentPartName = eventData.Get<string>("ContentPartName");
var diff = (DiffDictionary<string, string>)Model.Diff;
var diff = (DiffDictionary<string, string>)Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contenttype-eventsummary">
@T("Settings for the content part {0} attached to the content type {1} were changed:", Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))

View File

@@ -6,7 +6,7 @@
@{
var eventData = (IDictionary<string, object>) Model.EventData;
var contentTypeName = eventData.Get<string>("ContentTypeName");
var diff = (DiffDictionary<string, string>) Model.Diff;
var diff = (DiffDictionary<string, string>) Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contenttype-eventsummary">
@T("Settings for the content type {0} were changed:", Html.ContentTypeEditLink(contentTypeName))

View File

@@ -6,7 +6,7 @@
@{
var eventData = (IDictionary<string, object>) Model.EventData;
var contentTypeName = eventData.Get<string>("ContentTypeName");
var diff = (DiffDictionary<string, string>) Model.Diff;
var diff = (DiffDictionary<string, string>) Model.Diff ?? new DiffDictionary<string, string>();
}
<section class="audittrail-contenttype-eventsummary">
@T("Settings for the content type {0} were changed:", Html.ContentTypeEditLink(contentTypeName))