mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Incremental work on #184.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Orchard.AuditTrail.Helpers {
|
||||
public static class XmlHelper {
|
||||
public static XElement Parse(string xml) {
|
||||
if (String.IsNullOrEmpty(xml))
|
||||
return null;
|
||||
|
||||
try {
|
||||
return XElement.Parse(xml);
|
||||
}
|
||||
catch (Exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -84,6 +84,7 @@
|
||||
<Content Include="Styles\audittrail-display.css" />
|
||||
<Content Include="Styles\audittrail-disabledcontent.css" />
|
||||
<Content Include="Styles\audittrail-part.css" />
|
||||
<Content Include="Styles\audittrail-contenttype-event.css" />
|
||||
<Content Include="Styles\audittrail-settings-event.css" />
|
||||
<Content Include="Styles\audittrail-settings.css" />
|
||||
<Content Include="Styles\menu.audit-trail-admin.css" />
|
||||
@@ -108,7 +109,7 @@
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-PartAdded.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-PartRemoved.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-Removed.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-Role-PermissionAdded.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-Role-PermissionRemoved.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-Role-RoleCreated.cshtml" />
|
||||
@@ -129,6 +130,8 @@
|
||||
<Content Include="Views\AuditTrailFilter-Common-Date-To.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml" />
|
||||
<Content Include="Views\AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
@@ -169,6 +172,7 @@
|
||||
<Compile Include="Handlers\AuditTrailTrimmingSettingsPartHandler.cs" />
|
||||
<Compile Include="Helpers\FiltersExtensions.cs" />
|
||||
<Compile Include="Helpers\DateTimeExtensions.cs" />
|
||||
<Compile Include="Helpers\XmlHelper.cs" />
|
||||
<Compile Include="Helpers\StringExtensions.cs" />
|
||||
<Compile Include="ImportExport\AuditTrailExportStep.cs" />
|
||||
<Compile Include="ImportExport\AuditTrailExportHandler.cs" />
|
||||
@@ -191,7 +195,11 @@
|
||||
<Compile Include="Providers\Content\IDiffGramAnalyzer.cs" />
|
||||
<Compile Include="Services\AuditTrailTrimmingBackgroundTask.cs" />
|
||||
<Compile Include="Shapes\AuditTrailFilterShapes.cs" />
|
||||
<Compile Include="Shapes\AuditTrailEventShapeAlteration.cs" />
|
||||
<Compile Include="Shapes\ContentTypeSettingsUpdatedEventShape.cs" />
|
||||
<Compile Include="Shapes\AuditTrailSettingsEventShape.cs" />
|
||||
<Compile Include="Services\Models\Diff.cs" />
|
||||
<Compile Include="Services\Models\DiffDictionary.cs" />
|
||||
<Compile Include="ViewModels\AuditTrailCategorySettingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\AuditTrailEventDescriptorSettingViewModel.cs" />
|
||||
<Compile Include="ViewModels\AuditTrailEventSettingsViewModel.cs" />
|
||||
|
@@ -19,6 +19,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition {
|
||||
public const string Removed = "Removed";
|
||||
public const string PartAdded = "PartAdded";
|
||||
public const string PartRemoved = "PartRemoved";
|
||||
public const string TypeDisplayNameUpdated = "TypeDisplayNameUpdated";
|
||||
public const string TypeSettingsUpdated = "TypeSettingsUpdated";
|
||||
public const string PartSettingsUpdated = "PartSettingsUpdated";
|
||||
|
||||
@@ -28,6 +29,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition {
|
||||
.Event(this, Removed, T("Removed"), T("A content type was removed."), enableByDefault: true)
|
||||
.Event(this, PartAdded, T("Part added"), T("A content part was added to a content type."), enableByDefault: true)
|
||||
.Event(this, PartRemoved, T("Part removed"), T("A content part was removed from a content type."), enableByDefault: true)
|
||||
.Event(this, TypeDisplayNameUpdated, T("Type display name updated"), T("The display name of a content type was updated."), enableByDefault: true)
|
||||
.Event(this, TypeSettingsUpdated, T("Type settings updated"), T("The settings of a content type were updated."), enableByDefault: true)
|
||||
.Event(this, PartSettingsUpdated, T("Part settings updated"), T("The settings of a content part on a content type were updated."), enableByDefault: true);
|
||||
|
||||
|
@@ -1,9 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.AuditTrail.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.MetaData.Services;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.ContentTypes.Services;
|
||||
using Orchard.Environment.Extensions;
|
||||
|
||||
namespace Orchard.AuditTrail.Providers.ContentDefinition {
|
||||
@@ -11,46 +16,81 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition {
|
||||
public class GlobalContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase {
|
||||
private readonly IAuditTrailManager _auditTrailManager;
|
||||
private readonly IWorkContextAccessor _wca;
|
||||
private readonly IContentDefinitionService _contentDefinitionService;
|
||||
private string _oldContentTypeDisplayName;
|
||||
private SettingsDictionary _oldContentTypeSettings;
|
||||
private readonly ISettingsFormatter _settingsFormatter;
|
||||
|
||||
public GlobalContentDefinitionEditorEvents(
|
||||
IAuditTrailManager auditTrailManager,
|
||||
IWorkContextAccessor wca,
|
||||
IContentDefinitionService contentDefinitionService,
|
||||
ISettingsFormatter settingsFormatter) {
|
||||
|
||||
public GlobalContentDefinitionEditorEvents(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) {
|
||||
_auditTrailManager = auditTrailManager;
|
||||
_wca = wca;
|
||||
_contentDefinitionService = contentDefinitionService;
|
||||
_settingsFormatter = settingsFormatter;
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentTypeName", builder.Name}
|
||||
};
|
||||
RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.TypeSettingsUpdated, eventData, builder.Name);
|
||||
yield break;
|
||||
public override void TypeEditorUpdating(ContentTypeDefinitionBuilder definition) {
|
||||
var contentType = _contentDefinitionService.GetType(definition.Name);
|
||||
_oldContentTypeDisplayName = contentType.DisplayName;
|
||||
_oldContentTypeSettings = new SettingsDictionary(contentType.Settings);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
public override void TypeEditorUpdated(ContentTypeDefinitionBuilder builder) {
|
||||
var contentTypeDefinition = builder.Build();
|
||||
var newDisplayName = contentTypeDefinition.DisplayName;
|
||||
var newSettings = contentTypeDefinition.Settings;
|
||||
|
||||
if (newDisplayName != _oldContentTypeDisplayName) {
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentTypeName", builder.Name},
|
||||
{"OldDisplayName", _oldContentTypeDisplayName},
|
||||
{"NewDisplayName", newDisplayName}
|
||||
};
|
||||
RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.TypeDisplayNameUpdated, eventData, contentTypeDefinition.Name);
|
||||
}
|
||||
|
||||
if (!AreEqual(newSettings, _oldContentTypeSettings)) {
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentTypeName", builder.Name},
|
||||
{"OldSettings", ToXml(_oldContentTypeSettings)},
|
||||
{"NewSettings", ToXml(newSettings)}
|
||||
};
|
||||
RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.TypeSettingsUpdated, eventData, contentTypeDefinition.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder) {
|
||||
// TODO: record current values
|
||||
}
|
||||
|
||||
public override void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder) {
|
||||
// TODO: compare old values with new values.
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentPartName", builder.Name},
|
||||
{"ContentTypeName", builder.TypeName}
|
||||
};
|
||||
RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.TypeName);
|
||||
yield break;
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentPartName", builder.Name}
|
||||
};
|
||||
RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name);
|
||||
yield break;
|
||||
}
|
||||
//public override void PartEditorUpdated(ContentPartDefinitionBuilder builder) {
|
||||
// var eventData = new Dictionary<string, object> {
|
||||
// {"ContentPartName", builder.Name}
|
||||
// };
|
||||
// RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name);
|
||||
//}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
var eventData = new Dictionary<string, object> {
|
||||
{"ContentFieldName", builder.Name},
|
||||
{"ContentFieldType", builder.FieldType},
|
||||
{"ContentPartName", builder.PartName}
|
||||
};
|
||||
RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName);
|
||||
yield break;
|
||||
}
|
||||
//public override void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder) {
|
||||
// var eventData = new Dictionary<string, object> {
|
||||
// {"ContentFieldName", builder.Name},
|
||||
// {"ContentFieldType", builder.FieldType},
|
||||
// {"ContentPartName", builder.PartName}
|
||||
// };
|
||||
// RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName);
|
||||
//}
|
||||
|
||||
private void RecordContentTypeAuditTrail(string eventName, IDictionary<string, object> eventData, string contentTypeName) {
|
||||
_auditTrailManager.CreateRecord<ContentTypeAuditTrailEventProvider>(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName);
|
||||
@@ -59,5 +99,16 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition {
|
||||
private void RecordContentPartAuditTrail(string eventName, IDictionary<string, object> eventData, string contentPartName) {
|
||||
_auditTrailManager.CreateRecord<ContentPartAuditTrailEventProvider>(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartName);
|
||||
}
|
||||
|
||||
private string ToXml(SettingsDictionary settings) {
|
||||
return _settingsFormatter.Map(settings).ToString(SaveOptions.DisableFormatting);
|
||||
}
|
||||
|
||||
private bool AreEqual(SettingsDictionary a, SettingsDictionary b) {
|
||||
var xml1 = ToXml(a);
|
||||
var xml2 = ToXml(b);
|
||||
|
||||
return String.Equals(xml1, xml2, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,6 @@
|
||||
namespace Orchard.AuditTrail.Services.Models {
|
||||
public class Diff<T> {
|
||||
public T OldValue { get; set; }
|
||||
public T NewValue { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.AuditTrail.Services.Models {
|
||||
public class DiffDictionary<TKey, TValue> : Dictionary<TKey, Diff<TValue>> {}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using Orchard.AuditTrail.Helpers;
|
||||
using Orchard.AuditTrail.Services;
|
||||
using Orchard.AuditTrail.Services.Models;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
|
||||
namespace Orchard.AuditTrail.Shapes {
|
||||
public abstract class AuditTrailEventShapeAlteration<T> : IShapeTableProvider where T : IAuditTrailEventProvider {
|
||||
protected abstract string EventName { get; }
|
||||
|
||||
public void Discover(ShapeTableBuilder builder) {
|
||||
builder.Describe("AuditTrailEvent").OnDisplaying(context => {
|
||||
var descriptor = (AuditTrailEventDescriptor) context.Shape.Descriptor;
|
||||
if (descriptor.Event != EventNameExtensions.GetFullyQualifiedEventName<T>(EventName))
|
||||
return;
|
||||
|
||||
OnAlterShape(context);
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void OnAlterShape(ShapeDisplayingContext context) {}
|
||||
}
|
||||
}
|
@@ -1,36 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.AuditTrail.Helpers;
|
||||
using Orchard.AuditTrail.Models;
|
||||
using Orchard.AuditTrail.Providers.AuditTrail;
|
||||
using Orchard.AuditTrail.Services;
|
||||
using Orchard.AuditTrail.Services.Models;
|
||||
using Orchard.AuditTrail.ViewModels;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.Environment;
|
||||
|
||||
namespace Orchard.AuditTrail.Shapes {
|
||||
public class AuditTrailSettingsEventShape : IShapeTableProvider {
|
||||
public class AuditTrailSettingsEventShape : AuditTrailEventShapeAlteration<SettingsAuditTrailEventProvider> {
|
||||
private readonly Work<IAuditTrailManager> _auditTrailManager;
|
||||
public AuditTrailSettingsEventShape(Work<IAuditTrailManager> auditTrailManager) {
|
||||
_auditTrailManager = auditTrailManager;
|
||||
}
|
||||
|
||||
public void Discover(ShapeTableBuilder builder) {
|
||||
builder.Describe("AuditTrailEvent").OnDisplaying(context => {
|
||||
var descriptor = (AuditTrailEventDescriptor) context.Shape.Descriptor;
|
||||
if (descriptor.Event != EventNameExtensions.GetFullyQualifiedEventName<SettingsAuditTrailEventProvider>(SettingsAuditTrailEventProvider.EventsChanged))
|
||||
return;
|
||||
protected override string EventName {
|
||||
get { return SettingsAuditTrailEventProvider.EventsChanged; }
|
||||
}
|
||||
|
||||
var eventData = (IDictionary<string, object>)context.Shape.EventData;
|
||||
var oldSettings = _auditTrailManager.Value.DeserializeProviderConfiguration((string)eventData["OldSettings"]);
|
||||
var newSettings = _auditTrailManager.Value.DeserializeProviderConfiguration((string)eventData["NewSettings"]);
|
||||
var diff = GetDiffQuery(oldSettings, newSettings).ToArray();
|
||||
protected override void OnAlterShape(ShapeDisplayingContext context) {
|
||||
var eventData = (IDictionary<string, object>)context.Shape.EventData;
|
||||
var oldSettings = _auditTrailManager.Value.DeserializeProviderConfiguration((string)eventData["OldSettings"]);
|
||||
var newSettings = _auditTrailManager.Value.DeserializeProviderConfiguration((string)eventData["NewSettings"]);
|
||||
var diff = GetDiffQuery(oldSettings, newSettings).ToArray();
|
||||
|
||||
context.Shape.OldSettings = oldSettings;
|
||||
context.Shape.NewSettings = newSettings;
|
||||
context.Shape.Diff = diff;
|
||||
});
|
||||
context.Shape.OldSettings = oldSettings;
|
||||
context.Shape.NewSettings = newSettings;
|
||||
context.Shape.Diff = diff;
|
||||
}
|
||||
|
||||
private IEnumerable<AuditTrailEventDescriptorSettingViewModel> GetDiffQuery(IEnumerable<AuditTrailEventSetting> oldSettings, IEnumerable<AuditTrailEventSetting> newSettings) {
|
||||
|
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.AuditTrail.Helpers;
|
||||
using Orchard.AuditTrail.Providers.ContentDefinition;
|
||||
using Orchard.AuditTrail.Services.Models;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.MetaData.Services;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
|
||||
namespace Orchard.AuditTrail.Shapes {
|
||||
public class ContentTypeSettingsUpdatedEventShape : AuditTrailEventShapeAlteration<ContentTypeAuditTrailEventProvider> {
|
||||
private readonly ISettingsFormatter _settingsFormatter;
|
||||
public ContentTypeSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) {
|
||||
_settingsFormatter = settingsFormatter;
|
||||
}
|
||||
|
||||
protected override string EventName {
|
||||
get { return ContentTypeAuditTrailEventProvider.TypeSettingsUpdated; }
|
||||
}
|
||||
|
||||
protected override void OnAlterShape(ShapeDisplayingContext context) {
|
||||
var eventData = (IDictionary<string, object>)context.Shape.EventData;
|
||||
var oldSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["OldSettings"]));
|
||||
var newSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["NewSettings"]));
|
||||
var diff = GetDiff(oldSettings, newSettings);
|
||||
|
||||
context.Shape.OldSettings = oldSettings;
|
||||
context.Shape.NewSettings = newSettings;
|
||||
context.Shape.Diff = diff;
|
||||
}
|
||||
|
||||
private static DiffDictionary<string, string> GetDiff(SettingsDictionary oldSettings, SettingsDictionary newSettings) {
|
||||
var dictionary = new DiffDictionary<string, string>();
|
||||
|
||||
BuildDiff(dictionary, newSettings, oldSettings);
|
||||
BuildDiff(dictionary, oldSettings, newSettings);
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static void BuildDiff(DiffDictionary<string, string> dictionary, SettingsDictionary settingsA, SettingsDictionary settingsB) {
|
||||
|
||||
foreach (var settingA in settingsB) {
|
||||
var b = settingsA.ContainsKey(settingA.Key) ? settingsA[settingA.Key] : default(string);
|
||||
|
||||
if (b != settingA.Value) {
|
||||
dictionary[settingA.Key] = new Diff<string> {
|
||||
NewValue = settingA.Value,
|
||||
OldValue = b
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
section.audittrail-contenttype-event h2 strong {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
section.audittrail-contenttype-event table.items {
|
||||
width: auto;
|
||||
-moz-min-width: 600px;
|
||||
-ms-min-width: 600px;
|
||||
-o-min-width: 600px;
|
||||
-webkit-min-width: 600px;
|
||||
min-width: 600px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
section.audittrail-contenttype-event table.items thead th {
|
||||
font-weight: bold;
|
||||
}
|
@@ -3,7 +3,6 @@
|
||||
var diff = (IList<AuditTrailEventDescriptorSettingViewModel>)Model.Diff;
|
||||
var descriptions = String.Join("<br/>", diff.Select(x => T("<strong>{0}</strong> ({1}) was <strong>{2}</strong>", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text));
|
||||
}
|
||||
|
||||
<section class="audittrail-settings-summary">
|
||||
<section>
|
||||
@Html.Raw(descriptions)
|
||||
</section>
|
@@ -6,7 +6,6 @@
|
||||
var diff = (IList<AuditTrailEventDescriptorSettingViewModel>)Model.Diff;
|
||||
var groups = diff.GroupBy(x => x.Descriptor.CategoryDescriptor.Name).OrderBy(x => x.Key.Text);
|
||||
}
|
||||
|
||||
<section class="audittrail-settings-event">
|
||||
<table class="audittrail-events items">
|
||||
<thead>
|
||||
|
@@ -0,0 +1,11 @@
|
||||
@using Orchard.AuditTrail.Helpers
|
||||
@{
|
||||
var eventData = (IDictionary<string, object>) Model.EventData;
|
||||
var contentTypeName = eventData.Get<string>("ContentTypeName");
|
||||
var oldDisplayName = eventData.Get<string>("OldDisplayName");
|
||||
var newDisplayName = eventData.Get<string>("NewDisplayName");
|
||||
}
|
||||
|
||||
<section>
|
||||
@T("The display name for the <strong>{0}</strong> content type was changed from <strong>{1}</strong> to <strong>{2}</strong>.", contentTypeName, oldDisplayName, newDisplayName)
|
||||
</section>
|
@@ -0,0 +1,18 @@
|
||||
@using Orchard.AuditTrail.Helpers
|
||||
@using Orchard.AuditTrail.Services.Models
|
||||
@functions {
|
||||
string ToFriendlyEmpty(string value) {
|
||||
return String.IsNullOrWhiteSpace(value) ? Html.Encode("<empty>") : value;
|
||||
}
|
||||
}
|
||||
@{
|
||||
var eventData = (IDictionary<string, object>) Model.EventData;
|
||||
var contentTypeName = eventData.Get<string>("ContentTypeName");
|
||||
var diff = (DiffDictionary<string, string>) Model.Diff;
|
||||
var descriptions = String.Join("<br/>", diff.Select(x => T("<strong>{0}</strong> was changed from <strong>{1}</strong> to <strong>{2}</strong>.", x.Key, ToFriendlyEmpty(x.Value.OldValue), ToFriendlyEmpty(x.Value.NewValue)).Text));
|
||||
}
|
||||
|
||||
<section>
|
||||
@T("The following <strong>{0}</strong> settings were changed:", contentTypeName)<br/>
|
||||
@Html.Raw(descriptions)
|
||||
</section>
|
@@ -1,9 +1,36 @@
|
||||
@using Orchard.AuditTrail.Helpers
|
||||
@using Orchard.AuditTrail.Services.Models
|
||||
@{
|
||||
Style.Include("audittrail-contenttype-event.css");
|
||||
}
|
||||
@functions {
|
||||
static string ToFriendlyEmpty(string value) {
|
||||
return String.IsNullOrWhiteSpace(value) ? "<empty>" : value;
|
||||
}
|
||||
}
|
||||
@{
|
||||
var eventData = (IDictionary<string, object>) Model.EventData;
|
||||
var contentTypeName = eventData.Get<string>("ContentTypeName");
|
||||
var differences = (DiffDictionary<string, string>) Model.Diff;
|
||||
}
|
||||
|
||||
<section class="audittrail-contenttype-summary">
|
||||
@T("Settings for the <strong>{0}</strong> content type were updated.", contentTypeName)
|
||||
<section class="audittrail-contenttype-event">
|
||||
<h2>@T("The following <strong>{0}</strong> settings were changed", contentTypeName)</h2>
|
||||
<table class="items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@T("Setting")</th>
|
||||
<th>@T("From")</th>
|
||||
<th>@T("To")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="audittrail-category">
|
||||
@foreach (var diff in differences) {
|
||||
<tr>
|
||||
<td>@diff.Key</td>
|
||||
<td>@ToFriendlyEmpty(diff.Value.OldValue)</td>
|
||||
<td>@ToFriendlyEmpty(diff.Value.NewValue)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
@@ -99,33 +99,39 @@ namespace Orchard.ContentTypes.Services {
|
||||
typeBuilder.DisplayedAs(typeViewModel.DisplayName);
|
||||
|
||||
// allow extensions to alter type configuration
|
||||
_contentDefinitionEditorEvents.TypeEditorUpdating(typeBuilder);
|
||||
typeViewModel.Templates = _contentDefinitionEditorEvents.TypeEditorUpdate(typeBuilder, updater);
|
||||
_contentDefinitionEditorEvents.TypeEditorUpdated(typeBuilder);
|
||||
|
||||
foreach (var part in typeViewModel.Parts) {
|
||||
var partViewModel = part;
|
||||
|
||||
// enable updater to be aware of changing part prefix
|
||||
updater._prefix = secondHalf => string.Format("{0}.{1}", partViewModel.Prefix, secondHalf);
|
||||
updater._prefix = secondHalf => String.Format("{0}.{1}", partViewModel.Prefix, secondHalf);
|
||||
|
||||
// allow extensions to alter typePart configuration
|
||||
typeBuilder.WithPart(partViewModel.PartDefinition.Name, typePartBuilder => {
|
||||
_contentDefinitionEditorEvents.TypePartEditorUpdating(typePartBuilder);
|
||||
partViewModel.Templates = _contentDefinitionEditorEvents.TypePartEditorUpdate(typePartBuilder, updater);
|
||||
_contentDefinitionEditorEvents.TypePartEditorUpdated(typePartBuilder);
|
||||
});
|
||||
|
||||
if (!partViewModel.PartDefinition.Fields.Any())
|
||||
continue;
|
||||
|
||||
_contentDefinitionManager.AlterPartDefinition(partViewModel.PartDefinition.Name, partBuilder => {
|
||||
var fieldFirstHalf = string.Format("{0}.{1}", partViewModel.Prefix, partViewModel.PartDefinition.Prefix);
|
||||
var fieldFirstHalf = String.Format("{0}.{1}", partViewModel.Prefix, partViewModel.PartDefinition.Prefix);
|
||||
foreach (var field in partViewModel.PartDefinition.Fields) {
|
||||
var fieldViewModel = field;
|
||||
|
||||
// enable updater to be aware of changing field prefix
|
||||
updater._prefix = secondHalf =>
|
||||
string.Format("{0}.{1}.{2}", fieldFirstHalf, fieldViewModel.Prefix, secondHalf);
|
||||
String.Format("{0}.{1}.{2}", fieldFirstHalf, fieldViewModel.Prefix, secondHalf);
|
||||
// allow extensions to alter partField configuration
|
||||
partBuilder.WithField(fieldViewModel.Name, partFieldBuilder => {
|
||||
_contentDefinitionEditorEvents.PartFieldEditorUpdating(partFieldBuilder);
|
||||
fieldViewModel.Templates = _contentDefinitionEditorEvents.PartFieldEditorUpdate(partFieldBuilder, updater);
|
||||
_contentDefinitionEditorEvents.PartFieldEditorUpdated(partFieldBuilder);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -142,7 +148,9 @@ namespace Orchard.ContentTypes.Services {
|
||||
|
||||
// allow extensions to alter partField configuration
|
||||
partBuilder.WithField(fieldViewModel.Name, partFieldBuilder => {
|
||||
_contentDefinitionEditorEvents.PartFieldEditorUpdating(partFieldBuilder);
|
||||
fieldViewModel.Templates = _contentDefinitionEditorEvents.PartFieldEditorUpdate(partFieldBuilder, updater);
|
||||
_contentDefinitionEditorEvents.PartFieldEditorUpdated(partFieldBuilder);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@@ -12,10 +12,19 @@ namespace Orchard.ContentManagement.MetaData {
|
||||
IEnumerable<TemplateViewModel> PartEditor(ContentPartDefinition definition);
|
||||
IEnumerable<TemplateViewModel> PartFieldEditor(ContentPartFieldDefinition definition);
|
||||
|
||||
|
||||
void TypeEditorUpdating(ContentTypeDefinitionBuilder builder);
|
||||
IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel);
|
||||
void TypeEditorUpdated(ContentTypeDefinitionBuilder builder);
|
||||
void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder);
|
||||
IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel);
|
||||
void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder);
|
||||
void PartEditorUpdating(ContentPartDefinitionBuilder builder);
|
||||
IEnumerable<TemplateViewModel> PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel);
|
||||
void PartEditorUpdated(ContentPartDefinitionBuilder builder);
|
||||
void PartFieldEditorUpdating(ContentPartFieldDefinitionBuilder builder);
|
||||
IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel);
|
||||
void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder);
|
||||
}
|
||||
|
||||
public abstract class ContentDefinitionEditorEventsBase : IContentDefinitionEditorEvents {
|
||||
@@ -35,22 +44,38 @@ namespace Orchard.ContentManagement.MetaData {
|
||||
return Enumerable.Empty<TemplateViewModel>();
|
||||
}
|
||||
|
||||
public virtual void TypeEditorUpdating(ContentTypeDefinitionBuilder builder) {}
|
||||
|
||||
public virtual IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
return Enumerable.Empty<TemplateViewModel>();
|
||||
}
|
||||
|
||||
public virtual void TypeEditorUpdated(ContentTypeDefinitionBuilder builder) { }
|
||||
|
||||
public virtual void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder) {}
|
||||
|
||||
public virtual IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
return Enumerable.Empty<TemplateViewModel>();
|
||||
}
|
||||
|
||||
public virtual void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder) { }
|
||||
|
||||
public virtual void PartEditorUpdating(ContentPartDefinitionBuilder builder) {}
|
||||
|
||||
public virtual IEnumerable<TemplateViewModel> PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
return Enumerable.Empty<TemplateViewModel>();
|
||||
}
|
||||
|
||||
public virtual void PartEditorUpdated(ContentPartDefinitionBuilder builder) { }
|
||||
|
||||
public virtual void PartFieldEditorUpdating(ContentPartFieldDefinitionBuilder builder) {}
|
||||
|
||||
public virtual IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
return Enumerable.Empty<TemplateViewModel>();
|
||||
}
|
||||
|
||||
public virtual void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder) {}
|
||||
|
||||
protected static TemplateViewModel DefinitionTemplate<TModel>(TModel model) {
|
||||
return DefinitionTemplate(model, typeof(TModel).Name, typeof(TModel).Name);
|
||||
}
|
||||
|
Reference in New Issue
Block a user