From fd9c9830b05894c6f5b73a1a229082d61f5c68d0 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 22 May 2014 15:11:50 +0200 Subject: [PATCH 001/116] Adding generated AuditTrail module. --- .../Modules/Orchard.AuditTrail/Module.txt | 12 ++ .../Orchard.AuditTrail.csproj | 131 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 37 +++++ .../Orchard.AuditTrail/Scripts/Web.config | 16 +++ .../Orchard.AuditTrail/Styles/Web.config | 16 +++ .../Modules/Orchard.AuditTrail/Web.config | 41 ++++++ src/Orchard.sln | 42 +++--- 7 files changed, 279 insertions(+), 16 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Properties/AssemblyInfo.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/Web.config create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/Web.config create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Web.config diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt new file mode 100644 index 000000000..f5f8bd196 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -0,0 +1,12 @@ +Name: AuditTrail +AntiForgery: enabled +Author: The Orchard Team +Website: http://orchardproject.net +Version: 1.8.1 +OrchardVersion: 1.8 +Description: Logs user initiated events, such as content changes, providing a trail for auditing. +Features: + Orchard.AuditTrail: + Name: AuditTrail + Description: Provides the core audit trail framework. + Category: Security \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj new file mode 100644 index 000000000..c60184847 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -0,0 +1,131 @@ + + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Orchard.AuditTrail + Orchard.AuditTrail + v4.5 + false + + + 4.0 + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + false + + + pdbonly + true + bin\ + TRACE + prompt + 4 + AllRules.ruleset + false + + + + + + + 3.5 + + + + False + ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll + + + + + + + + + + + + + + + + + + + + + + + + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} + Orchard.Framework + + + {9916839C-39FC-4CEB-A5AF-89CA7E87119F} + Orchard.Core + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + $(ProjectDir)\..\Manifests + + + + + + + + + + + + False + True + 45979 + / + + + False + True + http://orchard.codeplex.com + False + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..7823daea7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Orchard.AuditTrail")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("Orchard")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c5863d1d-f836-4ce8-8791-027ba14c6815")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/Web.config b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/Web.config new file mode 100644 index 000000000..817198995 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/Web.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/Web.config new file mode 100644 index 000000000..817198995 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/Web.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Web.config b/src/Orchard.Web/Modules/Orchard.AuditTrail/Web.config new file mode 100644 index 000000000..19b511cda --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Web.config @@ -0,0 +1,41 @@ + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.sln b/src/Orchard.sln index 3a8ea1bf9..68e001fdf 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +VisualStudioVersion = 12.0.30501.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}" EndProject @@ -240,6 +240,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Caching", "Orchard. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Azure.MediaServices", "Orchard.Web\Modules\Orchard.Azure.MediaServices\Orchard.Azure.MediaServices.csproj", "{14A96B1A-9DC9-44C8-A675-206329E15263}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.AuditTrail", "Orchard.Web\Modules\Orchard.AuditTrail\Orchard.AuditTrail.csproj", "{3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CodeCoverage|Any CPU = CodeCoverage|Any CPU @@ -998,15 +1000,31 @@ Global {14A96B1A-9DC9-44C8-A675-206329E15263}.FxCop|Any CPU.Build.0 = Release|Any CPU {14A96B1A-9DC9-44C8-A675-206329E15263}.Release|Any CPU.ActiveCfg = Release|Any CPU {14A96B1A-9DC9-44C8-A675-206329E15263}.Release|Any CPU.Build.0 = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Coverage|Any CPU.ActiveCfg = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.FxCop|Any CPU.ActiveCfg = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} + {F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {79AED36E-ABD0-4747-93D3-8722B042454B} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {D10AD48F-407D-4DB5-A328-173EC7CB010F} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {2FC1D9C8-446D-4414-B252-5E9FBE61EB63} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {5E5E7A21-C7B2-44D8-8593-2F9541AE041D} = {383DBA32-4A3E-48D1-AAC3-75377A694452} + {7354DF37-934B-46CF-A13C-455D5F5F5413} = {3E10BF6D-ADA5-417D-B36C-EBB0660B475E} + {33B1BC8D-E292-4972-A363-22056B207156} = {383DBA32-4A3E-48D1-AAC3-75377A694452} {CDE24A24-01D3-403C-84B9-37722E18DFB7} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {94E694A2-D140-468D-A277-C5FCE1D13E9B} = {3E10BF6D-ADA5-417D-B36C-EBB0660B475E} + {0DFA2E10-96C8-4E05-BC10-B710B97ECCDE} = {383DBA32-4A3E-48D1-AAC3-75377A694452} {17F86780-9A1F-4AA1-86F1-875EEC2730C7} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {0E7646E8-FE8F-43C1-8799-D97860925EC4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} @@ -1014,6 +1032,7 @@ Global {5D0F00F0-26C9-4785-AD61-B85710C60EB0} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {954CA994-D204-468B-9D69-51F6AD3E1C29} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {72457126-E118-4171-A08F-9A709EE4B7FC} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} = {902528F6-1444-42A3-8B75-A54B775B539C} {05660F47-D649-48BD-9DED-DF4E01E7CFF9} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {14C049FD-B35B-415A-A824-87F26B26E7FD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {8F116B06-1C0E-4E4C-9A0A-D2FAB851E768} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} @@ -1024,6 +1043,7 @@ Global {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {74492CBC-7201-417E-BC29-28B4C25A58B0} {C889167C-E52C-4A65-A419-224B3D1B957D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {137906EA-15FE-4AD8-A6A0-27528F0477D6} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {3420C92A-747F-4990-BA08-F2C9531E44AD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} @@ -1031,14 +1051,18 @@ Global {2AD6973D-C7BB-416E-89FE-EEE34664E05F} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {99002B65-86F7-415E-BF4A-381AA8AB9CCC} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {4A4595EF-6C37-4F99-96ED-4AE0B9E438D3} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {43D0EC0B-1955-4566-8D31-7B9102DA1703} = {902528F6-1444-42A3-8B75-A54B775B539C} {FC1D74E8-7A4D-48F4-83DE-95C6173780C4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {FE5C5947-D2D5-42C5-992A-13D672946135} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {9CD5C81F-5828-4384-8474-2E2BE71D5EDD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {6F759635-13D7-4E94-BCC9-80445D63F117} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} = {902528F6-1444-42A3-8B75-A54B775B539C} {3158C928-888C-4A84-8BC1-4A8257489538} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {3F72A4E9-7B72-4260-B010-C16EC54F9BAF} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {E07AFA7E-7B36-44C3-A537-AFCCAA93EA7A} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {5531E894-D259-45A3-AA61-26DBE720C1CE} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {2969635F-D9C3-4D01-890D-437B46659690} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {3787DDE5-E5C8-4841-BDA7-DCB325388064} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {475B6C45-B27C-438B-8966-908B9D6D1077} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {66FCCD76-2761-47E3-8D11-B45D0001DDAA} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} @@ -1061,20 +1085,6 @@ Global {085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {7528BF74-25C7-4ABE-883A-443B4EEC4776} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {14A96B1A-9DC9-44C8-A675-206329E15263} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} - {ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {2FC1D9C8-446D-4414-B252-5E9FBE61EB63} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {E07AFA7E-7B36-44C3-A537-AFCCAA93EA7A} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {2969635F-D9C3-4D01-890D-437B46659690} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} - {5E5E7A21-C7B2-44D8-8593-2F9541AE041D} = {383DBA32-4A3E-48D1-AAC3-75377A694452} - {33B1BC8D-E292-4972-A363-22056B207156} = {383DBA32-4A3E-48D1-AAC3-75377A694452} - {0DFA2E10-96C8-4E05-BC10-B710B97ECCDE} = {383DBA32-4A3E-48D1-AAC3-75377A694452} - {CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {74492CBC-7201-417E-BC29-28B4C25A58B0} - {7354DF37-934B-46CF-A13C-455D5F5F5413} = {3E10BF6D-ADA5-417D-B36C-EBB0660B475E} - {94E694A2-D140-468D-A277-C5FCE1D13E9B} = {3E10BF6D-ADA5-417D-B36C-EBB0660B475E} - {43D0EC0B-1955-4566-8D31-7B9102DA1703} = {902528F6-1444-42A3-8B75-A54B775B539C} - {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} = {902528F6-1444-42A3-8B75-A54B775B539C} - {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} = {902528F6-1444-42A3-8B75-A54B775B539C} + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} EndGlobalSection EndGlobal From 0c0f2b91a43dfc07f6a3ee5a2e6c0d669d6f73fc Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 23 May 2014 22:32:34 +0200 Subject: [PATCH 002/116] Incremental work on audit trail services and UI. --- .../Modules/Orchard.AuditTrail/AdminMenu.cs | 15 ++ .../Controllers/AdminController.cs | 57 +++++++ .../Drivers/AuditTrailPartDriver.cs | 20 +++ .../Handlers/GlobalContentHandler.cs | 46 ++++++ .../Modules/Orchard.AuditTrail/Migrations.cs | 25 +++ .../Models/AuditTrailContext.cs | 12 ++ .../Models/AuditTrailCreateContext.cs | 3 + .../Models/AuditTrailEventDescriptor.cs | 11 ++ .../Models/AuditTrailEventRecord.cs | 14 ++ .../Models/AuditTrailEventTypeDescriptor.cs | 10 ++ .../Models/AuditTrailPart.cs | 10 ++ .../Models/DescribeContext.cs | 30 ++++ .../Orchard.AuditTrail/Models/DescribeFor.cs | 31 ++++ .../Orchard.AuditTrail.csproj | 66 +++++++- .../Modules/Orchard.AuditTrail/Permissions.cs | 24 +++ .../ContentAuditTrailEventProvider.cs | 21 +++ .../Recipes/audit-trail.recipe.xml | 19 +++ .../Services/AuditTrailEventProviderBase.cs | 7 + .../Services/AuditTrailManager.cs | 151 ++++++++++++++++++ .../Services/IAuditTrailEventHandler.cs | 8 + .../Services/IAuditTrailEventProvider.cs | 8 + .../Services/IAuditTrailManager.cs | 16 ++ .../Orchard.AuditTrail/Styles/admin.css | 48 ++++++ .../Styles/menu.audit-trail-admin.css | 7 + .../Styles/menu.audit-trail.png | Bin 0 -> 1104 bytes .../ViewModels/AuditTrailDetailsViewModel.cs | 5 + .../ViewModels/AuditTrailViewModel.cs | 10 ++ .../Views/Admin/Detail.cshtml | 7 + .../Views/Admin/Index.cshtml | 27 ++++ ...uditTrailEvent-Content.SummaryAdmin.cshtml | 27 ++++ .../Views/AuditTrailEvent-Content.cshtml | 21 +++ .../Views/AuditTrailEvent.SummaryAdmin.cshtml | 23 +++ .../Views/AuditTrailEvent.cshtml | 15 ++ .../EditorTemplates/Parts.AuditTrail.cshtml | 1 + 34 files changed, 788 insertions(+), 7 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs new file mode 100644 index 000000000..84a8843d1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs @@ -0,0 +1,15 @@ +using Orchard.UI.Navigation; + +namespace Orchard.AuditTrail { + public class AdminMenu : Component, INavigationProvider { + + public string MenuName { get { return "admin"; } } + + public void GetNavigation(NavigationBuilder builder) { + builder.AddImageSet("audit-trail") + .Add(T("Audit Trail"), "12", menuItem => menuItem + .Action("Index", "Admin", new { area = "Orchard.AuditTrail" }) + .Permission(Permissions.ManageAuditTrail)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs new file mode 100644 index 000000000..7c99b3534 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -0,0 +1,57 @@ +using System; +using System.Linq; +using System.Web.Mvc; +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.ViewModels; +using Orchard.DisplayManagement.Shapes; +using Orchard.Security; +using Orchard.UI.Navigation; + +namespace Orchard.AuditTrail.Controllers { + public class AdminController : Controller { + private readonly IAuthorizer _authorizer; + private readonly IAuditTrailManager _auditTrailManager; + private readonly IOrchardServices _services; + + public AdminController(IAuditTrailManager auditTrailManager, IOrchardServices services) { + _auditTrailManager = auditTrailManager; + _services = services; + _authorizer = services.Authorizer; + New = _services.New; + } + + public dynamic New { get; private set; } + + public ActionResult Index(PagerParameters pagerParameters) { + if(!_authorizer.Authorize(Permissions.ManageAuditTrail)) + return new HttpUnauthorizedResult(); + + var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters); + var pageOfData = _auditTrailManager.GetPage(pager.Page, pager.PageSize); + var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); + var list = New.List(); + + list.AddRange(pageOfData.Select(x => _auditTrailManager.BuildDisplay(x, "SummaryAdmin")).ToArray()); + var viewModel = new AuditTrailViewModel { + Records = pageOfData, + List = list, + Pager = pagerShape + }; + + return View(viewModel); + } + + public ActionResult Detail(int id) { + if (!_authorizer.Authorize(Permissions.ManageAuditTrail)) + return new HttpUnauthorizedResult(); + + var record = _auditTrailManager.GetRecord(id); + var recordShape = _auditTrailManager.BuildDisplay(record, "Detail"); + var viewModel = new AuditTrailDetailsViewModel { + Record = recordShape + }; + return View(viewModel); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs new file mode 100644 index 000000000..41c332748 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -0,0 +1,20 @@ +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; + +namespace Orchard.AuditTrail.Drivers { + public class AuditTrailPartDriver : ContentPartDriver { + protected override DriverResult Editor(AuditTrailPart part, dynamic shapeHelper) { + return Editor(part, null, shapeHelper); + } + + protected override DriverResult Editor(AuditTrailPart part, IUpdateModel updater, dynamic shapeHelper) { + return ContentShape("Parts_AuditTrail_Edit", () => { + if (updater != null) { + updater.TryUpdateModel(part, Prefix, null, null); + } + return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail", Prefix: Prefix); + }); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs new file mode 100644 index 000000000..6e06212df --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Providers; +using Orchard.AuditTrail.Services; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Handlers; + +namespace Orchard.AuditTrail.Handlers { + public class GlobalContentHandler : ContentHandler { + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + private readonly IContentManager _contentManager; + + public GlobalContentHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca, IContentManager contentManager) { + _auditTrailManager = auditTrailManager; + _wca = wca; + _contentManager = contentManager; + } + + protected override void Created(CreateContentContext context) { + RecordAuditTrail(ContentAuditTrailEventProvider.Created, context.ContentItem); + } + + protected override void Updated(UpdateContentContext context) { + RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem); + } + + protected override void Published(PublishContentContext context) { + RecordAuditTrail(ContentAuditTrailEventProvider.Published, context.ContentItem); + } + + protected override void Unpublished(PublishContentContext context) { + RecordAuditTrail(ContentAuditTrailEventProvider.Unpublished, context.ContentItem); + } + + protected override void Removed(RemoveContentContext context) { + RecordAuditTrail(ContentAuditTrailEventProvider.Removed, context.ContentItem); + } + + private void RecordAuditTrail(string eventName, IContent content) { + var title = _contentManager.GetItemMetadata(content).DisplayText; + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, content, new Dictionary { + {"Title", title} + }); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs new file mode 100644 index 000000000..abe7452d8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -0,0 +1,25 @@ +using System; +using Orchard.ContentManagement.MetaData; +using Orchard.Core.Contents.Extensions; +using Orchard.Data.Migration; + +namespace Orchard.AuditTrail { + public class Migrations : DataMigrationImpl { + public int Create() { + SchemaBuilder.CreateTable("AuditTrailEventRecord", table => table + .Column("Id", c => c.PrimaryKey().Identity()) + .Column("CreatedUtc") + .Column("UserName", c => c.WithLength(64)) + .Column("Event", c => c.WithLength(64)) + .Column("Category", c => c.WithLength(64)) + .Column("ContentItemVersion_Id") + .Column("EventData", c => c.Unlimited())); + + ContentDefinitionManager.AlterPartDefinition("AuditTrailPart", part => part + .Attachable() + .WithDescription("Enables the user to enter a comment about the change when saving a content item.")); + + return 1; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs new file mode 100644 index 000000000..1a721c5c8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.Security; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailContext { + public string Event { get; set; } + public IUser User { get; set; } + public IContent Content { get; set; } + public IDictionary EventData { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs new file mode 100644 index 000000000..f636ec5dd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.AuditTrail.Models { + public class AuditTrailCreateContext : AuditTrailContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs new file mode 100644 index 000000000..1ef369202 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs @@ -0,0 +1,11 @@ +using Orchard.Localization; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailEventDescriptor { + public string Category { get; set; } + public string Event { get; set; } + public LocalizedString Name { get; set; } + public LocalizedString Description { get; set; } + public bool IsEnabledByDefault { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs new file mode 100644 index 000000000..9948b7225 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs @@ -0,0 +1,14 @@ +using System; +using Orchard.ContentManagement.Records; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailEventRecord { + public virtual int Id { get; set; } + public virtual DateTime CreatedUtc { get; set; } + public virtual string UserName { get; set; } + public virtual string Event { get; set; } + public virtual string Category { get; set; } + public virtual ContentItemVersionRecord ContentItemVersion { get; set; } + public virtual string EventData { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs new file mode 100644 index 000000000..1a90f6ce3 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Orchard.Localization; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailCategoryDescriptor { + public string Category { get; set; } + public LocalizedString Name { get; set; } + public IEnumerable Events { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs new file mode 100644 index 000000000..c1c8162b9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs @@ -0,0 +1,10 @@ +using Orchard.ContentManagement; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailPart : ContentPart { + public string LastComment { + get { return this.Retrieve(x => x.LastComment); } + set { this.Store(x => x.LastComment, value); } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs new file mode 100644 index 000000000..fd692069a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using Orchard.Localization; + +namespace Orchard.AuditTrail.Models { + public class DescribeContext { + private readonly Dictionary _describes = new Dictionary(); + + public IEnumerable Describe() { + var query = + from d in _describes.Values + select new AuditTrailCategoryDescriptor { + Category = d.Category, + Name = d.Name, + Events = d.Events + }; + + return query.ToArray(); + } + + public DescribeFor For(string category, LocalizedString name) { + DescribeFor describeFor; + if (!_describes.TryGetValue(category, out describeFor)) { + describeFor = new DescribeFor(category, name); + _describes[category] = describeFor; + } + return describeFor; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs new file mode 100644 index 000000000..2cc6d66e1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using Orchard.Localization; + +namespace Orchard.AuditTrail.Models { + public class DescribeFor { + private readonly IList _events = new List(); + + public DescribeFor(string category, LocalizedString name) { + Category = category; + Name = name; + } + + public IEnumerable Events { + get { return _events; } + } + + public string Category { get; private set; } + public LocalizedString Name { get; private set; } + + public DescribeFor Event(string eventName, LocalizedString name, LocalizedString description, bool enableByDefault = false) { + _events.Add(new AuditTrailEventDescriptor { + Category = Category, + Event = eventName, + Name = name, + Description = description, + IsEnabledByDefault = enableByDefault + }); + return this; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index c60184847..84e3135c5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -1,4 +1,4 @@ - + @@ -19,6 +19,11 @@ 4.0 + false + + + + true @@ -43,6 +48,10 @@ + + False + ..\..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll + @@ -62,17 +71,15 @@ + + + + - - - - - - @@ -84,6 +91,51 @@ Orchard.Core + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs new file mode 100644 index 000000000..dbf8ad8d1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Orchard.Environment.Extensions.Models; +using Orchard.Security.Permissions; + +namespace Orchard.AuditTrail { + public class Permissions : IPermissionProvider { + public static readonly Permission ManageAuditTrail = new Permission { Description = "Manage Audit Trail", Name = "ManageAuditTrail" }; + + public virtual Feature Feature { get; set; } + + public IEnumerable GetPermissions() { + yield return ManageAuditTrail; + } + + public IEnumerable GetDefaultStereotypes() { + return new[] { + new PermissionStereotype { + Name = "Administrator", + Permissions = new[] {ManageAuditTrail} + } + }; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs new file mode 100644 index 000000000..35db47e0b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs @@ -0,0 +1,21 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Providers { + public class ContentAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string Created = "Created"; + public const string Saved = "Saved"; + public const string Published = "Published"; + public const string Unpublished = "Unpublished"; + public const string Removed = "Removed"; + + public override void Describe(DescribeContext context) { + context.For("Content", T("Content")) + .Event(Created, T("Created"), T("Content was created."), enableByDefault: true) + .Event(Saved, T("Saved"), T("Content was saved."), enableByDefault: true) + .Event(Published, T("Published"), T("Content was published."), enableByDefault: true) + .Event(Unpublished, T("Unpublished"), T("Content was unpublished."), enableByDefault: true) + .Event(Removed, T("Removed"), T("Content was deleted."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml new file mode 100644 index 000000000..5774a8009 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml @@ -0,0 +1,19 @@ + + + + Audit Trail + Attaches the AuditTrailPart to the Page content type. + The Orchard Team + http://orchardproject.net + developer + 1.0 + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs new file mode 100644 index 000000000..f22326613 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs @@ -0,0 +1,7 @@ +using Orchard.AuditTrail.Models; + +namespace Orchard.AuditTrail.Services { + public abstract class AuditTrailEventProviderBase : Component, IAuditTrailEventProvider { + public abstract void Describe(DescribeContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs new file mode 100644 index 000000000..e47278338 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Newtonsoft.Json; +using Orchard.AuditTrail.Models; +using Orchard.Collections; +using Orchard.ContentManagement; +using Orchard.Data; +using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Shapes; +using Orchard.Logging; +using Orchard.Security; +using Orchard.Services; + +namespace Orchard.AuditTrail.Services { + public class AuditTrailManager : Component, IAuditTrailManager { + private readonly IRepository _auditTrailRepository; + private readonly IEnumerable _providers; + private readonly IClock _clock; + private readonly IAuditTrailEventHandler _auditTrailEventHandlers; + + public AuditTrailManager( + IRepository auditTrailRepository, + IEnumerable providers, + IClock clock, + IAuditTrailEventHandler auditTrailEventHandlers, + IShapeFactory shapeFactory) { + + _auditTrailRepository = auditTrailRepository; + _providers = providers; + _clock = clock; + _auditTrailEventHandlers = auditTrailEventHandlers; + New = shapeFactory; + } + + public dynamic New { get; set; } + + public IPageOfItems GetPage(int page, int pageSize) { + var totalItemCount = _auditTrailRepository.Table.Count(); + var startIndex = (page - 1)*pageSize; + var pageOfData = _auditTrailRepository.Table.Skip(startIndex).Take(pageSize); + + return new PageOfItems(pageOfData) { + PageNumber = page, + PageSize = pageSize, + TotalItemCount = totalItemCount + }; + } + + public AuditTrailEventRecord GetRecord(int id) { + return _auditTrailRepository.Get(id); + } + + public AuditTrailEventRecord Record(string eventName, IUser user, IContent content = null, IDictionary eventData = null) { + if(eventData == null) + eventData = new Dictionary(); + + var createContext = new AuditTrailCreateContext { + Event = eventName, + User = user, + Content = content, + EventData = eventData + }; + + _auditTrailEventHandlers.Create(createContext); + + var eventDescriptor = GetEventDescriptor(eventName); + + var record = new AuditTrailEventRecord { + Category = eventDescriptor.Category, + Event = eventDescriptor.Event, + ContentItemVersion = content != null ? content.ContentItem.VersionRecord : null, + CreatedUtc = _clock.UtcNow, + UserName = user != null ? user.UserName : null, + EventData = SerializeEventData(eventData) + }; + + _auditTrailRepository.Create(record); + return record; + } + + public IEnumerable Describe() { + var context = new DescribeContext(); + foreach (var provider in _providers) { + provider.Describe(context); + } + return context.Describe(); + } + + public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) { + var eventData = DeserializeEventData(record.EventData); + var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData); + var metaData = (ShapeMetadata)auditTrailEventShape.Metadata; + metaData.DisplayType = displayType; + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); + metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, record.Event)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, record.Event)); + return auditTrailEventShape; + } + + private AuditTrailEventDescriptor GetEventDescriptor(string eventName) { + var categoryDescriptors = Describe(); + var eventDescriptorQuery = from c in categoryDescriptors + from e in c.Events + where e.Event == eventName + select e; + var eventDescriptors = eventDescriptorQuery.ToArray(); + + if (!eventDescriptors.Any()) { + throw new ArgumentException(String.Format("No event named '{0}' exists.", eventName)); + } + + // TODO: Do we actually want this requirement, or should we support multiple events with the same name across categories? + // SOLVED: We will use the fully qualified provider type name + event name. + if (eventDescriptors.Count() > 1) + throw new InvalidProgramException(String.Format("The specified event name occurs {0} times. Event names must be unique across categories.", eventDescriptors.Count())); + + return eventDescriptors.First(); + } + + private string SerializeEventData(IDictionary eventData) { + try { + var json = JsonConvert.SerializeObject(eventData, Formatting.None); + var xml = JsonConvert.DeserializeXNode(json, deserializeRootElementName: "EventData"); + return xml.ToString(SaveOptions.DisableFormatting); + } + catch (Exception ex) { + Logger.Error(ex, "Error during serialization of eventData"); + } + return null; + } + + private IDictionary DeserializeEventData(string eventData) { + if(String.IsNullOrWhiteSpace(eventData)) + return new Dictionary(); + + try { + var node = XDocument.Parse(eventData); + var json = JsonConvert.SerializeXNode(node, Formatting.None, omitRootObject: true); + return JsonConvert.DeserializeObject>(json); + } + catch (Exception ex) { + Logger.Error(ex, "Error during deserialization of eventData"); + } + return new Dictionary(); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs new file mode 100644 index 000000000..c27cfe6fa --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs @@ -0,0 +1,8 @@ +using Orchard.AuditTrail.Models; +using Orchard.Events; + +namespace Orchard.AuditTrail.Services { + public interface IAuditTrailEventHandler : IEventHandler { + void Create(AuditTrailCreateContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs new file mode 100644 index 000000000..babfdcead --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs @@ -0,0 +1,8 @@ +using Orchard.AuditTrail.Models; +using Orchard.Events; + +namespace Orchard.AuditTrail.Services { + public interface IAuditTrailEventProvider : IEventHandler { + void Describe(DescribeContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs new file mode 100644 index 000000000..7a45676ea --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Orchard.AuditTrail.Models; +using Orchard.Collections; +using Orchard.ContentManagement; +using Orchard.Security; + +namespace Orchard.AuditTrail.Services { + public interface IAuditTrailManager : IDependency { + IPageOfItems GetPage(int page, int pageSize); + AuditTrailEventRecord GetRecord(int id); + AuditTrailEventRecord Record(string eventName, IUser user, IContent content = null, IDictionary eventData = null); + IEnumerable Describe(); + dynamic BuildDisplay(AuditTrailEventRecord record, string displayType); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css new file mode 100644 index 000000000..056a5803d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -0,0 +1,48 @@ +.audit-trail-filter { + margin-bottom: 1em; +} + +.audit-trail-list .info { + line-height: 25px; +} + +.audit-trail-list ul { + margin: 1em 0 1em 0; + border: 1px solid #eaeaea; +} + +.audit-trail-list li { + border-bottom: 1px solid #eaeaea; + padding: 1em; +} + +.audit-trail-list li:nth-child(even) { + background: #F9F9F9; +} + +.audit-trail-list li.last { + border-bottom: none; +} + +.audit-trail-list .audit-trail-record .event-header { + +} + +.audit-trail-list .audit-trail-record .event-header .event-name { + float: left; +} + +.audit-trail-list .audit-trail-record .event-header .event-name a { + font-size: 1.231em; +} + +.audit-trail-list .audit-trail-record .event-header .event-actions { + float: right; +} + +.audit-trail-list .audit-trail-record .event-details { +} + +.audit-trail-record-details fieldset legend span { + font-size: 0.8em; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css new file mode 100644 index 000000000..33d56b7cb --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css @@ -0,0 +1,7 @@ +.navicon-audit-trail { + background-image:url(menu.audit-trail.png) !important; +} + +.navicon-audit-trail:hover { + background-position:0 -30px !important; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png new file mode 100644 index 0000000000000000000000000000000000000000..a35718a2a6ecd43a030767a5df59dd097c0a9dd7 GIT binary patch literal 1104 zcmaJ=TWHfz7>+pI7*2&L=)A>LP>0Q>Yn=_NvuRpaU1zPu6+yNvIbE}woS2;2c0LFy zf^UKs_8=3~2Opdu47|?iKtxcy%nRu7!3&B^6vPXP;z?br57xlRx$u48|NZ~@&;DrJ z+M4RRYJwnY!YyJ9&ol90tES@roQ`kpc$$lX3A70&QC2bm;a6Z6Aj6u}4Pro2^4o8M zCW4r}SdAx8BGSssP@^RqL+3ODvk9W9IcG?68X&R@bgR0LdVgt{B2~plwR<9L#0Y?t z+R|%+O}%Y#xi>9)6{>kP*_7k4fCi96=Cp0P#pirfL6^sC`cwC&g1rS+zQggat#c}GA^%^<9K%?&#fdUJ_<)Ol_Vb%Lld#^&PSyX zGI)l`X0vp*fre%`!+E`4hIKJ6mlGqLR$fO^&Z%3DqJju4*;EarLY=e~r7oC3J_99i? ze82<}f@U1TZN(}^QxHKb1r0I~AeXhPx&pJ-@&Y^(;lsLxBwYq!(MMqcT2&R^Ev#&4 zWQ9=B<@a-3ut8WQ3PEmF(Cv2#LSraUcTje{oP&oFfB~y0}-JUUUt#WHh7@b)p-v0#Dw;e#2MYWkh6YmWCEyw^M$o%G_+$4~V5(9iSkip6i9Pxr5# zcY=wo-|Xl+{`T{RiX9h(d}nh0lKLxc2U@p02_VjgaYxw26$@QK0AA1J-E7jB> zeRs;mt34IwK;6!z=3e62&7+RleP6r2>>1f`_WLA%M_L=N7+&{b(5 QTb%YA4+q=CGeYO?UqyFvR{#J2 literal 0 HcmV?d00001 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs new file mode 100644 index 000000000..bfe8ecb07 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs @@ -0,0 +1,5 @@ +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailDetailsViewModel { + public dynamic Record { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs new file mode 100644 index 000000000..c50502952 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Models; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailViewModel { + public IEnumerable Records { get; set; } + public dynamic List { get; set; } + public dynamic Pager { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml new file mode 100644 index 000000000..4cf8473f7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml @@ -0,0 +1,7 @@ +@model Orchard.AuditTrail.ViewModels.AuditTrailDetailsViewModel +@{ + Style.Include("admin.css"); +} +
+ @Display(Model.Record) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml new file mode 100644 index 000000000..c428f783d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -0,0 +1,27 @@ +@model Orchard.AuditTrail.ViewModels.AuditTrailViewModel +@{ + Style.Include("admin.css"); +} +
+
+ + + +
+ +
+
+ @if (!Model.Records.Any()) { +

@T("There are no records to display.")

+ } + else { + @Display(Model.List) + } +
+
+ @Display(Model.Pager) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml new file mode 100644 index 000000000..aa1d480d9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -0,0 +1,27 @@ +@using Orchard.AuditTrail.Models +@{ + var record = (AuditTrailEventRecord)Model.Record; + var eventData = (IDictionary) Model.EventData; + var detailsUrl = Url.Action("Detail", "Admin", new {id = record.Id, area = "Orchard.AuditTrail"}); + var title = eventData.ContainsKey("Title") ? (string)eventData["Title"] : "-"; +} +
+
+
+
+ @record.Event - @record.Category +
+ +
+
+
+ @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @if (!String.IsNullOrWhiteSpace(record.UserName)) { + @T(" | ")@T("by {0}", record.UserName) + } + @T(" | ")@title + @T(" | ")@T("version {0}", record.ContentItemVersion.Number) +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml new file mode 100644 index 000000000..1303ca741 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -0,0 +1,21 @@ +@using Orchard.AuditTrail.Models +@{ + var record = (AuditTrailEventRecord)Model.Record; +} +
+
+ @record.Event - @record.Category +
+ @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @if (!String.IsNullOrWhiteSpace(record.UserName)) { + @T(" | ")@record.UserName + } +
+ @if (record.ContentItemVersion != null) { +
+ Welcome to Orchard! + @T(" | ")@T("version {0}", record.ContentItemVersion.Number) +
+ } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml new file mode 100644 index 000000000..545e82d63 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml @@ -0,0 +1,23 @@ +@using Orchard.AuditTrail.Models +@{ + var record = (AuditTrailEventRecord)Model.Record; + var detailsUrl = Url.Action("Detail", "Admin", new {id = record.Id, area = "Orchard.AuditTrail"}); +} +
+
+
+
+ @record.Event - @record.Category +
+ +
+
+
+ @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @if (!String.IsNullOrWhiteSpace(record.UserName)) { + @T(" | ")@record.UserName + } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml new file mode 100644 index 000000000..83605f367 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml @@ -0,0 +1,15 @@ +@using Orchard.AuditTrail.Models +@{ + var record = (AuditTrailEventRecord)Model.Record; +} +
+
+ @record.Event - @record.Category +
+ @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @if (!String.IsNullOrWhiteSpace(record.UserName)) { + @T(" | ")@record.UserName + } +
+
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml @@ -0,0 +1 @@ + \ No newline at end of file From b0d7814906c1a29c71e0f7c645899cba8e84b356 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 25 May 2014 14:47:15 +0200 Subject: [PATCH 003/116] Incremental work on filtering. --- .../Controllers/AdminController.cs | 40 ++++-- ...iver.cs => AuditTrailCommentPartDriver.cs} | 10 +- .../Drivers/ContentsDriver.cs | 10 ++ .../Handlers/AuditTrailEventHandler.cs | 18 +++ .../Handlers/GlobalContentHandler.cs | 24 +++- .../Helpers/EventDataHelper.cs | 15 ++ .../Helpers/EventNameHelper.cs | 14 ++ .../Modules/Orchard.AuditTrail/Migrations.cs | 9 +- ...tor.cs => AuditTrailCategoryDescriptor.cs} | 0 .../Models/AuditTrailCommentPart.cs | 10 ++ .../Models/AuditTrailContext.cs | 9 +- .../Models/AuditTrailCreateContext.cs | 4 +- .../Models/AuditTrailEventDescriptor.cs | 2 +- .../Models/AuditTrailEventRecord.cs | 5 +- .../Models/AuditTrailFilterParameters.cs | 11 ++ .../Models/AuditTrailOrderBy.cs | 6 + .../Models/AuditTrailPart.cs | 10 -- .../Orchard.AuditTrail/Models/DescribeFor.cs | 12 +- .../Orchard.AuditTrail.csproj | 22 ++- .../Modules/Orchard.AuditTrail/Placement.info | 6 + .../ContentAuditTrailEventProvider.cs | 10 +- .../Recipes/audit-trail.recipe.xml | 4 +- .../Services/AuditTrailEventDisplayBuilder.cs | 33 +++++ .../Services/AuditTrailManager.cs | 131 +++++++----------- .../Services/EventDataSerializer.cs | 36 +++++ .../IAuditTrailEventDisplayBuilder.cs | 7 + .../Services/IAuditTrailManager.cs | 52 ++++++- .../Services/IEventDataSerializer.cs | 8 ++ .../Orchard.AuditTrail/Styles/admin.css | 34 +---- .../AuditTrailEventSummaryViewModel.cs | 10 ++ .../ViewModels/AuditTrailFilterViewModel.cs | 17 +++ .../ViewModels/AuditTrailViewModel.cs | 8 +- .../Views/Admin/Index.cshtml | 59 ++++++-- ...uditTrailEvent-Content.SummaryAdmin.cshtml | 33 ++--- .../Views/AuditTrailEvent-Content.cshtml | 16 +-- .../EditorTemplates/Parts.AuditTrail.cshtml | 1 - .../Parts.AuditTrailComment.cshtml | 9 ++ ...ts.Contents.AuditTrail.SummaryAdmin.cshtml | 1 + 38 files changed, 496 insertions(+), 210 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/{AuditTrailPartDriver.cs => AuditTrailCommentPartDriver.cs} (50%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/ContentsDriver.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs rename src/Orchard.Web/Modules/Orchard.AuditTrail/Models/{AuditTrailEventTypeDescriptor.cs => AuditTrailCategoryDescriptor.cs} (100%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventDisplayBuilder.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IEventDataSerializer.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 7c99b3534..2e3a76160 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -4,7 +4,7 @@ using System.Web.Mvc; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; using Orchard.AuditTrail.ViewModels; -using Orchard.DisplayManagement.Shapes; +using Orchard.Localization.Services; using Orchard.Security; using Orchard.UI.Navigation; @@ -13,30 +13,50 @@ namespace Orchard.AuditTrail.Controllers { private readonly IAuthorizer _authorizer; private readonly IAuditTrailManager _auditTrailManager; private readonly IOrchardServices _services; + private readonly IAuditTrailEventDisplayBuilder _displayBuilder; + private readonly IDateServices _dateServices; - public AdminController(IAuditTrailManager auditTrailManager, IOrchardServices services) { + public AdminController(IAuditTrailManager auditTrailManager, IOrchardServices services, IAuditTrailEventDisplayBuilder displayBuilder, IDateServices dateServices) { _auditTrailManager = auditTrailManager; _services = services; + _displayBuilder = displayBuilder; + _dateServices = dateServices; _authorizer = services.Authorizer; New = _services.New; } public dynamic New { get; private set; } - public ActionResult Index(PagerParameters pagerParameters) { + public ActionResult Index(PagerParameters pagerParameters, AuditTrailFilterViewModel filterParameters) { if(!_authorizer.Authorize(Permissions.ManageAuditTrail)) return new HttpUnauthorizedResult(); var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters); - var pageOfData = _auditTrailManager.GetPage(pager.Page, pager.PageSize); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { + UserName = filterParameters.UserName, + FilterKey = filterParameters.FilterKey, + FilterValue = filterParameters.FilterValue, + From = _dateServices.ConvertFromLocalString(filterParameters.From.Date, filterParameters.From.Time), + To = _dateServices.ConvertFromLocalString(filterParameters.To.Date, filterParameters.To.Time), + }, filterParameters.OrderBy); var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var list = New.List(); + var eventDescriptors = from c in _auditTrailManager.Describe() + from e in c.Events + select e; + var recordViewModels = from record in pageOfData + let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) + where descriptor != null + select new AuditTrailEventSummaryViewModel { + Record = record, + EventDescriptor = descriptor, + CategoryDescriptor = descriptor.CategoryDescriptor, + SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") + }; - list.AddRange(pageOfData.Select(x => _auditTrailManager.BuildDisplay(x, "SummaryAdmin")).ToArray()); var viewModel = new AuditTrailViewModel { - Records = pageOfData, - List = list, - Pager = pagerShape + Records = recordViewModels, + Pager = pagerShape, + Filter = filterParameters }; return View(viewModel); @@ -47,7 +67,7 @@ namespace Orchard.AuditTrail.Controllers { return new HttpUnauthorizedResult(); var record = _auditTrailManager.GetRecord(id); - var recordShape = _auditTrailManager.BuildDisplay(record, "Detail"); + var recordShape = _displayBuilder.BuildDisplay(record, "Detail"); var viewModel = new AuditTrailDetailsViewModel { Record = recordShape }; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs similarity index 50% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs index 41c332748..2ae27de6f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs @@ -3,17 +3,17 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; namespace Orchard.AuditTrail.Drivers { - public class AuditTrailPartDriver : ContentPartDriver { - protected override DriverResult Editor(AuditTrailPart part, dynamic shapeHelper) { + public class AuditTrailCommentPartDriver : ContentPartDriver { + protected override DriverResult Editor(AuditTrailCommentPart part, dynamic shapeHelper) { return Editor(part, null, shapeHelper); } - protected override DriverResult Editor(AuditTrailPart part, IUpdateModel updater, dynamic shapeHelper) { - return ContentShape("Parts_AuditTrail_Edit", () => { + protected override DriverResult Editor(AuditTrailCommentPart part, IUpdateModel updater, dynamic shapeHelper) { + return ContentShape("Parts_AuditTrailComment_Edit", () => { if (updater != null) { updater.TryUpdateModel(part, Prefix, null, null); } - return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail", Prefix: Prefix); + return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrailComment", Prefix: Prefix); }); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/ContentsDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/ContentsDriver.cs new file mode 100644 index 000000000..1c72b15b4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/ContentsDriver.cs @@ -0,0 +1,10 @@ +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; + +namespace Orchard.AuditTrail.Drivers { + public class ContentsDriver : ContentPartDriver { + protected override DriverResult Display(ContentPart part, string displayType, dynamic shapeHelper) { + return ContentShape("Parts_Contents_AuditTrail_SummaryAdmin", () => shapeHelper.Parts_Contents_AuditTrail_SummaryAdmin()); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs new file mode 100644 index 000000000..700539037 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs @@ -0,0 +1,18 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; +using Orchard.ContentManagement; + +namespace Orchard.AuditTrail.Handlers { + public class AuditTrailEventHandler : IAuditTrailEventHandler { + public void Create(AuditTrailCreateContext context) { + var content = (IContent)context.Properties["Content"]; + var auditTrailPart = content != null ? content.As() : default(AuditTrailCommentPart); + + if (auditTrailPart == null) + return; + + context.Comment = auditTrailPart.Comment; + auditTrailPart.Comment = null; // Reset the comment. + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs index 6e06212df..3c7c415b1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs @@ -3,6 +3,7 @@ using Orchard.AuditTrail.Providers; using Orchard.AuditTrail.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; +using Orchard.ContentManagement.Records; namespace Orchard.AuditTrail.Handlers { public class GlobalContentHandler : ContentHandler { @@ -21,7 +22,8 @@ namespace Orchard.AuditTrail.Handlers { } protected override void Updated(UpdateContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem); + // TODO: Update ContentManager to expose the previous version of the updated content item. + RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem, context.ContentItem.VersionRecord); } protected override void Published(PublishContentContext context) { @@ -36,11 +38,25 @@ namespace Orchard.AuditTrail.Handlers { RecordAuditTrail(ContentAuditTrailEventProvider.Removed, context.ContentItem); } - private void RecordAuditTrail(string eventName, IContent content) { + private void RecordAuditTrail(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { var title = _contentManager.GetItemMetadata(content).DisplayText; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, content, new Dictionary { + + var properties = new Dictionary { + {"Content", content} + }; + + var eventData = new Dictionary { + {"ContentItemId", content.Id}, + {"ContentItemVersionId", content.ContentItem.VersionRecord.Id}, + {"ContentItemVersionNumber", content.ContentItem.VersionRecord.Number}, {"Title", title} - }); + }; + + if (previousContentItemVersion != null) { + eventData["PreviousContentItemVersionId"] = previousContentItemVersion.Id; + } + + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString()); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs new file mode 100644 index 000000000..1b0e00807 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Orchard.AuditTrail.Helpers { + public static class EventDataHelper { + public static T Get(this IDictionary eventData, string key) { + if (!eventData.ContainsKey(key)) + return default(T); + + var value = eventData[key]; + + return (T) Convert.ChangeType(value, typeof (T)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs new file mode 100644 index 000000000..a3199546e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs @@ -0,0 +1,14 @@ +using System; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Helpers { + internal static class EventNameHelper { + public static string GetFullyQualifiedEventName(string eventName) where T : IAuditTrailEventProvider { + return GetFullyQualifiedEventName(typeof(T), eventName); + } + + public static string GetFullyQualifiedEventName(Type providerType, string eventName) { + return String.Concat(providerType.FullName, ".", eventName); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs index abe7452d8..5704bdfd7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -10,12 +10,15 @@ namespace Orchard.AuditTrail { .Column("Id", c => c.PrimaryKey().Identity()) .Column("CreatedUtc") .Column("UserName", c => c.WithLength(64)) - .Column("Event", c => c.WithLength(64)) + .Column("Event", c => c.WithLength(256)) .Column("Category", c => c.WithLength(64)) .Column("ContentItemVersion_Id") - .Column("EventData", c => c.Unlimited())); + .Column("EventData", c => c.Unlimited()) + .Column("EventFilterKey", c => c.WithLength(16)) + .Column("EventFilterData", c => c.WithLength(256)) + .Column("Comment", c => c.Unlimited())); - ContentDefinitionManager.AlterPartDefinition("AuditTrailPart", part => part + ContentDefinitionManager.AlterPartDefinition("AuditTrailCommentPart", part => part .Attachable() .WithDescription("Enables the user to enter a comment about the change when saving a content item.")); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCategoryDescriptor.cs similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventTypeDescriptor.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCategoryDescriptor.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs new file mode 100644 index 000000000..77237d640 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs @@ -0,0 +1,10 @@ +using Orchard.ContentManagement; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailCommentPart : ContentPart { + public string Comment { + get { return this.Retrieve(x => x.Comment); } + set { this.Store(x => x.Comment, value); } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs index 1a721c5c8..55e067024 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs @@ -1,12 +1,17 @@ using System.Collections.Generic; -using Orchard.ContentManagement; using Orchard.Security; namespace Orchard.AuditTrail.Models { public class AuditTrailContext { + public AuditTrailContext() { + EventData = new Dictionary(); + } + public string Event { get; set; } public IUser User { get; set; } - public IContent Content { get; set; } + public IDictionary Properties { get; set; } public IDictionary EventData { get; set; } + public string EventFilterKey { get; set; } + public string EventFilterData { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs index f636ec5dd..7bf93afdb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs @@ -1,3 +1,5 @@ namespace Orchard.AuditTrail.Models { - public class AuditTrailCreateContext : AuditTrailContext {} + public class AuditTrailCreateContext : AuditTrailContext { + public string Comment { get; set; } + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs index 1ef369202..4368f4f4a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs @@ -2,7 +2,7 @@ using Orchard.Localization; namespace Orchard.AuditTrail.Models { public class AuditTrailEventDescriptor { - public string Category { get; set; } + public AuditTrailCategoryDescriptor CategoryDescriptor { get; set; } public string Event { get; set; } public LocalizedString Name { get; set; } public LocalizedString Description { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs index 9948b7225..f40fded26 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs @@ -1,5 +1,4 @@ using System; -using Orchard.ContentManagement.Records; namespace Orchard.AuditTrail.Models { public class AuditTrailEventRecord { @@ -8,7 +7,9 @@ namespace Orchard.AuditTrail.Models { public virtual string UserName { get; set; } public virtual string Event { get; set; } public virtual string Category { get; set; } - public virtual ContentItemVersionRecord ContentItemVersion { get; set; } public virtual string EventData { get; set; } + public virtual string EventFilterKey { get; set; } + public virtual string EventFilterData { get; set; } + public virtual string Comment { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs new file mode 100644 index 000000000..dae826587 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs @@ -0,0 +1,11 @@ +using System; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailFilterParameters { + public string FilterKey { get; set; } + public string FilterValue { get; set; } + public string UserName { get; set; } + public DateTime? From { get; set; } + public DateTime? To { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs new file mode 100644 index 000000000..f72899256 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs @@ -0,0 +1,6 @@ +namespace Orchard.AuditTrail.Models { + public enum AuditTrailOrderBy { + DateDescending, + EventAscending + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs deleted file mode 100644 index c1c8162b9..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Orchard.ContentManagement; - -namespace Orchard.AuditTrail.Models { - public class AuditTrailPart : ContentPart { - public string LastComment { - get { return this.Retrieve(x => x.LastComment); } - set { this.Store(x => x.LastComment, value); } - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs index 2cc6d66e1..2f0dd3c23 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Services; using Orchard.Localization; namespace Orchard.AuditTrail.Models { @@ -17,10 +19,14 @@ namespace Orchard.AuditTrail.Models { public string Category { get; private set; } public LocalizedString Name { get; private set; } - public DescribeFor Event(string eventName, LocalizedString name, LocalizedString description, bool enableByDefault = false) { + public DescribeFor Event(IAuditTrailEventProvider provider, string eventName, LocalizedString name, LocalizedString description, bool enableByDefault = false) { _events.Add(new AuditTrailEventDescriptor { - Category = Category, - Event = eventName, + CategoryDescriptor = new AuditTrailCategoryDescriptor { + Category = Category, + Name = Name, + Events = Events + }, + Event = EventNameHelper.GetFullyQualifiedEventName(provider.GetType(), eventName), Name = name, Description = description, IsEnabledByDefault = enableByDefault diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 84e3135c5..a64df20dd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -71,6 +71,7 @@ + @@ -80,6 +81,7 @@ + @@ -94,12 +96,22 @@ - - + + + + + + + + + + + + - + @@ -108,6 +120,8 @@ + + @@ -134,7 +148,7 @@ - + 10.0 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info new file mode 100644 index 000000000..e5c4dfd4f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs index 35db47e0b..5c3c8c7f5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs @@ -11,11 +11,11 @@ namespace Orchard.AuditTrail.Providers { public override void Describe(DescribeContext context) { context.For("Content", T("Content")) - .Event(Created, T("Created"), T("Content was created."), enableByDefault: true) - .Event(Saved, T("Saved"), T("Content was saved."), enableByDefault: true) - .Event(Published, T("Published"), T("Content was published."), enableByDefault: true) - .Event(Unpublished, T("Unpublished"), T("Content was unpublished."), enableByDefault: true) - .Event(Removed, T("Removed"), T("Content was deleted."), enableByDefault: true); + .Event(this, Created, T("Created"), T("Content was created."), enableByDefault: true) + .Event(this, Saved, T("Saved"), T("Content was saved."), enableByDefault: true) + .Event(this, Published, T("Published"), T("Content was published."), enableByDefault: true) + .Event(this, Unpublished, T("Unpublished"), T("Content was unpublished."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("Content was deleted."), enableByDefault: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml index 5774a8009..914e7d0b1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml @@ -2,7 +2,7 @@ Audit Trail - Attaches the AuditTrailPart to the Page content type. + Attaches the AuditTrailCommentPart to the Page content type. The Orchard Team http://orchardproject.net developer @@ -12,7 +12,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs new file mode 100644 index 000000000..dd08d9142 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -0,0 +1,33 @@ +using System; +using Orchard.AuditTrail.Models; +using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Shapes; + +namespace Orchard.AuditTrail.Services { + public class AuditTrailEventDisplayBuilder : IAuditTrailEventDisplayBuilder { + private readonly IEventDataSerializer _serializer; + private readonly IAuditTrailManager _auditTrailManager; + + public AuditTrailEventDisplayBuilder(IShapeFactory shapeFactory, IEventDataSerializer serializer, IAuditTrailManager auditTrailManager) { + _serializer = serializer; + _auditTrailManager = auditTrailManager; + New = shapeFactory; + } + + public dynamic New { get; set; } + + public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) { + var eventData = _serializer.Deserialize(record.EventData); + var descriptor = _auditTrailManager.Describe(record.Event); + var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData, Descriptor: descriptor); + var metaData = (ShapeMetadata)auditTrailEventShape.Metadata; + metaData.DisplayType = displayType; + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); + metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, record.Event)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, record.Event)); + return auditTrailEventShape; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index e47278338..2529ac508 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -1,47 +1,61 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Xml.Linq; -using Newtonsoft.Json; +using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; using Orchard.Collections; -using Orchard.ContentManagement; using Orchard.Data; -using Orchard.DisplayManagement; -using Orchard.DisplayManagement.Shapes; -using Orchard.Logging; using Orchard.Security; using Orchard.Services; namespace Orchard.AuditTrail.Services { public class AuditTrailManager : Component, IAuditTrailManager { private readonly IRepository _auditTrailRepository; - private readonly IEnumerable _providers; + private readonly IAuditTrailEventProvider _providers; private readonly IClock _clock; private readonly IAuditTrailEventHandler _auditTrailEventHandlers; + private readonly IEventDataSerializer _serializer; public AuditTrailManager( IRepository auditTrailRepository, - IEnumerable providers, - IClock clock, + IAuditTrailEventProvider providers, + IClock clock, IAuditTrailEventHandler auditTrailEventHandlers, - IShapeFactory shapeFactory) { + IEventDataSerializer serializer) { _auditTrailRepository = auditTrailRepository; _providers = providers; _clock = clock; _auditTrailEventHandlers = auditTrailEventHandlers; - New = shapeFactory; + _serializer = serializer; } - public dynamic New { get; set; } + public IPageOfItems GetRecords(int page, int pageSize, AuditTrailFilterParameters filter = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending) { + + var query = _auditTrailRepository.Table; - public IPageOfItems GetPage(int page, int pageSize) { - var totalItemCount = _auditTrailRepository.Table.Count(); - var startIndex = (page - 1)*pageSize; - var pageOfData = _auditTrailRepository.Table.Skip(startIndex).Take(pageSize); + if (filter != null) { + if (!String.IsNullOrWhiteSpace(filter.FilterKey)) query = query.Where(x => x.EventFilterKey == filter.FilterKey); + if (!String.IsNullOrWhiteSpace(filter.FilterValue)) query = query.Where(x => x.EventFilterData == filter.FilterValue); + if (!String.IsNullOrWhiteSpace(filter.UserName)) query = query.Where(x => x.UserName == filter.UserName); + if (filter.From != null) query = query.Where(x => x.CreatedUtc >= filter.From); + if (filter.To != null) query = query.Where(x => x.CreatedUtc <= filter.To); + } - return new PageOfItems(pageOfData) { + switch (orderBy) { + default: + query = query.OrderByDescending(x => x.CreatedUtc); + break; + case AuditTrailOrderBy.EventAscending: + query = query.OrderBy(x => x.Event); + break; + } + + var totalItemCount = query.Count(); + var startIndex = (page - 1) * pageSize; + var records = query.Skip(startIndex).Take(pageSize); + + return new PageOfItems(records) { PageNumber = page, PageSize = pageSize, TotalItemCount = totalItemCount @@ -52,28 +66,31 @@ namespace Orchard.AuditTrail.Services { return _auditTrailRepository.Get(id); } - public AuditTrailEventRecord Record(string eventName, IUser user, IContent content = null, IDictionary eventData = null) { - if(eventData == null) - eventData = new Dictionary(); + public AuditTrailEventRecord Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { + if (properties == null) properties = new Dictionary(); + if (eventData == null) eventData = new Dictionary(); - var createContext = new AuditTrailCreateContext { + var context = new AuditTrailCreateContext { Event = eventName, User = user, - Content = content, - EventData = eventData + Properties = properties, + EventData = eventData, + EventFilterKey = eventFilterKey, + EventFilterData = eventFilterData }; - _auditTrailEventHandlers.Create(createContext); - - var eventDescriptor = GetEventDescriptor(eventName); + _auditTrailEventHandlers.Create(context); + var eventDescriptor = Describe(eventName); var record = new AuditTrailEventRecord { - Category = eventDescriptor.Category, + Category = eventDescriptor.CategoryDescriptor.Category, Event = eventDescriptor.Event, - ContentItemVersion = content != null ? content.ContentItem.VersionRecord : null, CreatedUtc = _clock.UtcNow, UserName = user != null ? user.UserName : null, - EventData = SerializeEventData(eventData) + EventData = _serializer.Serialize(context.EventData), + EventFilterKey = context.EventFilterKey, + EventFilterData = context.EventFilterData, + Comment = context.Comment }; _auditTrailRepository.Create(record); @@ -82,70 +99,28 @@ namespace Orchard.AuditTrail.Services { public IEnumerable Describe() { var context = new DescribeContext(); - foreach (var provider in _providers) { - provider.Describe(context); - } + _providers.Describe(context); return context.Describe(); } - public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) { - var eventData = DeserializeEventData(record.EventData); - var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData); - var metaData = (ShapeMetadata)auditTrailEventShape.Metadata; - metaData.DisplayType = displayType; - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); - metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, record.Event)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, record.Event)); - return auditTrailEventShape; + public AuditTrailEventDescriptor Describe(string eventName) where T:IAuditTrailEventProvider { + var fullyQualifiedEventName = EventNameHelper.GetFullyQualifiedEventName(eventName); + return Describe(fullyQualifiedEventName); } - private AuditTrailEventDescriptor GetEventDescriptor(string eventName) { + public AuditTrailEventDescriptor Describe(string fullyQualifiedEventName) { var categoryDescriptors = Describe(); var eventDescriptorQuery = from c in categoryDescriptors from e in c.Events - where e.Event == eventName + where e.Event == fullyQualifiedEventName select e; var eventDescriptors = eventDescriptorQuery.ToArray(); if (!eventDescriptors.Any()) { - throw new ArgumentException(String.Format("No event named '{0}' exists.", eventName)); + throw new ArgumentException(String.Format("No event named '{0}' exists.", fullyQualifiedEventName)); } - // TODO: Do we actually want this requirement, or should we support multiple events with the same name across categories? - // SOLVED: We will use the fully qualified provider type name + event name. - if (eventDescriptors.Count() > 1) - throw new InvalidProgramException(String.Format("The specified event name occurs {0} times. Event names must be unique across categories.", eventDescriptors.Count())); - return eventDescriptors.First(); } - - private string SerializeEventData(IDictionary eventData) { - try { - var json = JsonConvert.SerializeObject(eventData, Formatting.None); - var xml = JsonConvert.DeserializeXNode(json, deserializeRootElementName: "EventData"); - return xml.ToString(SaveOptions.DisableFormatting); - } - catch (Exception ex) { - Logger.Error(ex, "Error during serialization of eventData"); - } - return null; - } - - private IDictionary DeserializeEventData(string eventData) { - if(String.IsNullOrWhiteSpace(eventData)) - return new Dictionary(); - - try { - var node = XDocument.Parse(eventData); - var json = JsonConvert.SerializeXNode(node, Formatting.None, omitRootObject: true); - return JsonConvert.DeserializeObject>(json); - } - catch (Exception ex) { - Logger.Error(ex, "Error during deserialization of eventData"); - } - return new Dictionary(); - } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs new file mode 100644 index 000000000..8f37e91fe --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Newtonsoft.Json; +using Orchard.Logging; + +namespace Orchard.AuditTrail.Services { + public class EventDataSerializer : Component, IEventDataSerializer { + public string Serialize(IDictionary eventData) { + try { + var json = JsonConvert.SerializeObject(eventData, Formatting.None); + var xml = JsonConvert.DeserializeXNode(json, deserializeRootElementName: "EventData"); + return xml.ToString(SaveOptions.DisableFormatting); + } + catch (Exception ex) { + Logger.Error(ex, "Error during serialization of eventData"); + } + return null; + } + + public IDictionary Deserialize(string eventData) { + if (String.IsNullOrWhiteSpace(eventData)) + return new Dictionary(); + + try { + var node = XDocument.Parse(eventData); + var json = JsonConvert.SerializeXNode(node, Formatting.None, omitRootObject: true); + return JsonConvert.DeserializeObject>(json); + } + catch (Exception ex) { + Logger.Error(ex, "Error during deserialization of eventData"); + } + return new Dictionary(); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventDisplayBuilder.cs new file mode 100644 index 000000000..85f6f94b4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventDisplayBuilder.cs @@ -0,0 +1,7 @@ +using Orchard.AuditTrail.Models; + +namespace Orchard.AuditTrail.Services { + public interface IAuditTrailEventDisplayBuilder : IDependency { + dynamic BuildDisplay(AuditTrailEventRecord record, string displayType); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 7a45676ea..9b9d25ea3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -2,15 +2,59 @@ using System.Collections.Generic; using Orchard.AuditTrail.Models; using Orchard.Collections; -using Orchard.ContentManagement; using Orchard.Security; namespace Orchard.AuditTrail.Services { public interface IAuditTrailManager : IDependency { - IPageOfItems GetPage(int page, int pageSize); + /// + /// Gets a page of event records. + /// + /// The page number to get records from. + /// The number of records to get. + /// The value to order by. + /// Optional. An object to filter the records on. + /// Returns a page of event records. + IPageOfItems GetRecords(int page, int pageSize, AuditTrailFilterParameters filter = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending); + + /// + /// Returns a single event record by ID. + /// + /// The event record ID. + /// Returns a single event record by ID. AuditTrailEventRecord GetRecord(int id); - AuditTrailEventRecord Record(string eventName, IUser user, IContent content = null, IDictionary eventData = null); + + /// + /// Records an audit trail event. + /// + /// The audit trail event provider type to determine the scope of the event name. + /// The shorthand name of the event + /// The user to associate with the event. This is typically the currently loggedin user. + /// A property bag of custom event data that could be useful for implementations. These values aren't stored. Use the eventData parameter to persist additional data with the event. + /// A property bag of custom event data that will be stored with the event record. + /// The name of a custom key to use when filtering events. + /// The value of a custom filter key to filter on. + /// Returns the created audit trail event record. + AuditTrailEventRecord Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; + + /// + /// Describes all audit trail events provided by the system. + /// + /// Returns a list of audit trail category descriptors. IEnumerable Describe(); - dynamic BuildDisplay(AuditTrailEventRecord record, string displayType); + + /// + /// Describes a single audit trail event. + /// + /// The scope of the specified event name. + /// The shorthand name of the event. + /// Returns a single audit trail event descriptor. + AuditTrailEventDescriptor Describe(string eventName) where T : IAuditTrailEventProvider; + + /// + /// Describes a single audit trail event. + /// + /// The fully qualified event name to describe. + /// Returns a single audit trail event descriptor. + AuditTrailEventDescriptor Describe(string fullyQualifiedEventName); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IEventDataSerializer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IEventDataSerializer.cs new file mode 100644 index 000000000..3fef8e8c4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IEventDataSerializer.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Orchard.AuditTrail.Services { + public interface IEventDataSerializer : IDependency { + string Serialize(IDictionary eventData); + IDictionary Deserialize(string eventData); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css index 056a5803d..b3eb28f2a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -6,38 +6,8 @@ line-height: 25px; } -.audit-trail-list ul { - margin: 1em 0 1em 0; - border: 1px solid #eaeaea; -} - -.audit-trail-list li { - border-bottom: 1px solid #eaeaea; - padding: 1em; -} - -.audit-trail-list li:nth-child(even) { - background: #F9F9F9; -} - -.audit-trail-list li.last { - border-bottom: none; -} - -.audit-trail-list .audit-trail-record .event-header { - -} - -.audit-trail-list .audit-trail-record .event-header .event-name { - float: left; -} - -.audit-trail-list .audit-trail-record .event-header .event-name a { - font-size: 1.231em; -} - -.audit-trail-list .audit-trail-record .event-header .event-actions { - float: right; +.audit-trail-list .event-content .version { + font-size: 0.8em; } .audit-trail-list .audit-trail-record .event-details { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs new file mode 100644 index 000000000..8048a3624 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs @@ -0,0 +1,10 @@ +using Orchard.AuditTrail.Models; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailEventSummaryViewModel { + public AuditTrailEventRecord Record { get; set; } + public AuditTrailEventDescriptor EventDescriptor { get; set; } + public AuditTrailCategoryDescriptor CategoryDescriptor { get; set; } + public dynamic SummaryShape { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs new file mode 100644 index 000000000..bb3fcd95a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs @@ -0,0 +1,17 @@ +using Orchard.AuditTrail.Models; +using Orchard.Core.Common.ViewModels; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailFilterViewModel { + public AuditTrailFilterViewModel() { + From = new DateTimeEditor { ShowDate = true, ShowTime = false}; + To = new DateTimeEditor { ShowDate = true, ShowTime = false }; + } + public string FilterKey { get; set; } + public string FilterValue { get; set; } + public string UserName { get; set; } + public DateTimeEditor From { get; set; } + public DateTimeEditor To { get; set; } + public AuditTrailOrderBy OrderBy { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs index c50502952..a2d313754 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs @@ -1,9 +1,13 @@ using System.Collections.Generic; -using Orchard.AuditTrail.Models; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailViewModel { - public IEnumerable Records { get; set; } + public AuditTrailViewModel() { + Filter = new AuditTrailFilterViewModel(); + } + + public AuditTrailFilterViewModel Filter { get; set; } + public IEnumerable Records { get; set; } public dynamic List { get; set; } public dynamic Pager { get; set; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index c428f783d..e973cfbca 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -1,15 +1,31 @@ -@model Orchard.AuditTrail.ViewModels.AuditTrailViewModel +@using Orchard.AuditTrail.Models +@model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ Style.Include("admin.css"); + var from = Model.Filter.From; + var to = Model.Filter.To; + var orderBy = Model.Filter.OrderBy; + var orderByItems = new List { + new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.DateDescending}, + new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.EventAscending}, + }; }
-
- - - -
+ @using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { +
+ @Html.Hidden("filterkey", Model.Filter.FilterKey) + @Html.Hidden("filtervalue", Model.Filter.FilterValue) + @Html.Label("username", T("User:").Text) + @Html.TextBox("username", Model.Filter.UserName, new { @class = "text" }) + @Html.LabelFor(m => from, T("Between:")) + @Html.EditorFor(m => from) + @Html.LabelFor(m => to, T("And:")) + @Html.EditorFor(m => to) + @Html.LabelFor(m => orderBy, T("Ordered by:")) + @Html.DropDownListFor(m => orderBy, orderByItems) + +
+ } @@ -19,7 +35,32 @@

@T("There are no records to display.")

} else { - @Display(Model.List) + + + + + + + + + + + + + + @foreach (var record in Model.Records) { + + + + + + + + + + } + +
@T("Event")@T("Category")@T("User")@T("Timestamp")@T("Comment")@T("Event Data")
@record.EventDescriptor.Name@record.CategoryDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment@Display(record.SummaryShape)@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
}
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index aa1d480d9..d2ac1a9bb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -1,27 +1,12 @@ -@using Orchard.AuditTrail.Models +@using Orchard.AuditTrail.Helpers @{ - var record = (AuditTrailEventRecord)Model.Record; var eventData = (IDictionary) Model.EventData; - var detailsUrl = Url.Action("Detail", "Admin", new {id = record.Id, area = "Orchard.AuditTrail"}); - var title = eventData.ContainsKey("Title") ? (string)eventData["Title"] : "-"; + var title = eventData.Get("Title"); + var contentItemId = eventData.Get("ContentItemId"); + var contentItemVersionNumber = eventData.Get("ContentItemVersionNumber"); } -
-
-
-
- @record.Event - @record.Category -
- -
-
-
- @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) - @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@T("by {0}", record.UserName) - } - @T(" | ")@title - @T(" | ")@T("version {0}", record.ContentItemVersion.Number) -
-
\ No newline at end of file + +
+ @T("version {0}", contentItemVersionNumber)@T(" - ") + @title +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 1303ca741..7d51518ab 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -1,21 +1,21 @@ -@using Orchard.AuditTrail.Models +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Models @{ var record = (AuditTrailEventRecord)Model.Record; + var descriptor = (AuditTrailEventDescriptor) Model.Descriptor; + var eventData = (IDictionary)Model.EventData; + var title = eventData.Get("Title"); + var contentItemId = eventData.Get("ContentItemId"); + var contentItemVersionNumber = eventData.Get("ContentItemVersionNumber"); }
- @record.Event - @record.Category + @descriptor.Name - @descriptor.CategoryDescriptor.Name
@Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) @if (!String.IsNullOrWhiteSpace(record.UserName)) { @T(" | ")@record.UserName }
- @if (record.ContentItemVersion != null) { -
- Welcome to Orchard! - @T(" | ")@T("version {0}", record.ContentItemVersion.Number) -
- }
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml deleted file mode 100644 index 5f282702b..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml new file mode 100644 index 000000000..fb15345bb --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml @@ -0,0 +1,9 @@ +@model Orchard.AuditTrail.Models.AuditTrailCommentPart +
+ @T("Audit Trail") +
+ @Html.LabelFor(m => m.Comment) + @Html.TextBoxFor(m => m.Comment, new { @class = "text large" }) + @T("Optionally provide a comment about this change. This comment will be stored as part of an audit trail event.") +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml new file mode 100644 index 000000000..54d6dc060 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml @@ -0,0 +1 @@ +@T("Audit Trail")@T(" | ") \ No newline at end of file From bb9d8818cf74b1105e6ceafb2f4cb5beabffebf1 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 25 May 2014 15:46:28 +0200 Subject: [PATCH 004/116] Incremental work on AuditTrailPart settings. --- ...tPartDriver.cs => AuditTrailPartDriver.cs} | 10 +++---- .../Handlers/AuditTrailEventHandler.cs | 2 +- .../Modules/Orchard.AuditTrail/Migrations.cs | 2 +- ...tTrailCommentPart.cs => AuditTrailPart.cs} | 2 +- .../Orchard.AuditTrail.csproj | 9 ++++-- .../Modules/Orchard.AuditTrail/Placement.info | 2 +- .../Recipes/audit-trail.recipe.xml | 4 +-- .../Settings/AuditTrailPartSettings.cs | 14 +++++++++ .../Settings/AuditTrailPartSettingsEvents.cs | 30 +++++++++++++++++++ .../AuditTrailPartSettings.cshtml | 15 ++++++++++ ...Comment.cshtml => Parts.AuditTrail.cshtml} | 0 11 files changed, 76 insertions(+), 14 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/{AuditTrailCommentPartDriver.cs => AuditTrailPartDriver.cs} (50%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Models/{AuditTrailCommentPart.cs => AuditTrailPart.cs} (81%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettingsEvents.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/{Parts.AuditTrailComment.cshtml => Parts.AuditTrail.cshtml} (100%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs similarity index 50% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 2ae27de6f..41c332748 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailCommentPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -3,17 +3,17 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; namespace Orchard.AuditTrail.Drivers { - public class AuditTrailCommentPartDriver : ContentPartDriver { - protected override DriverResult Editor(AuditTrailCommentPart part, dynamic shapeHelper) { + public class AuditTrailPartDriver : ContentPartDriver { + protected override DriverResult Editor(AuditTrailPart part, dynamic shapeHelper) { return Editor(part, null, shapeHelper); } - protected override DriverResult Editor(AuditTrailCommentPart part, IUpdateModel updater, dynamic shapeHelper) { - return ContentShape("Parts_AuditTrailComment_Edit", () => { + protected override DriverResult Editor(AuditTrailPart part, IUpdateModel updater, dynamic shapeHelper) { + return ContentShape("Parts_AuditTrail_Edit", () => { if (updater != null) { updater.TryUpdateModel(part, Prefix, null, null); } - return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrailComment", Prefix: Prefix); + return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail", Prefix: Prefix); }); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs index 700539037..d37ce91dd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs @@ -6,7 +6,7 @@ namespace Orchard.AuditTrail.Handlers { public class AuditTrailEventHandler : IAuditTrailEventHandler { public void Create(AuditTrailCreateContext context) { var content = (IContent)context.Properties["Content"]; - var auditTrailPart = content != null ? content.As() : default(AuditTrailCommentPart); + var auditTrailPart = content != null ? content.As() : default(AuditTrailPart); if (auditTrailPart == null) return; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs index 5704bdfd7..f399c1756 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -18,7 +18,7 @@ namespace Orchard.AuditTrail { .Column("EventFilterData", c => c.WithLength(256)) .Column("Comment", c => c.Unlimited())); - ContentDefinitionManager.AlterPartDefinition("AuditTrailCommentPart", part => part + ContentDefinitionManager.AlterPartDefinition("AuditTrailPart", part => part .Attachable() .WithDescription("Enables the user to enter a comment about the change when saving a content item.")); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs similarity index 81% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs index 77237d640..5a425c949 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCommentPart.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs @@ -1,7 +1,7 @@ using Orchard.ContentManagement; namespace Orchard.AuditTrail.Models { - public class AuditTrailCommentPart : ContentPart { + public class AuditTrailPart : ContentPart { public string Comment { get { return this.Retrieve(x => x.Comment); } set { this.Store(x => x.Comment, value); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index a64df20dd..d244f0be3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -82,6 +82,7 @@ + @@ -100,10 +101,12 @@ + + - + - + @@ -148,7 +151,7 @@ - + 10.0 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info index e5c4dfd4f..99196942a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -1,5 +1,5 @@  - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml index 914e7d0b1..5774a8009 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Recipes/audit-trail.recipe.xml @@ -2,7 +2,7 @@ Audit Trail - Attaches the AuditTrailCommentPart to the Page content type. + Attaches the AuditTrailPart to the Page content type. The Orchard Team http://orchardproject.net developer @@ -12,7 +12,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs new file mode 100644 index 000000000..8acda67e2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs @@ -0,0 +1,14 @@ +using System.Globalization; +using Orchard.ContentManagement.MetaData.Builders; + +namespace Orchard.AuditTrail.Settings { + public class AuditTrailPartSettings { + public bool ShowAuditTrailLink { get; set; } + public bool ShowAuditTrail { get; set; } + + public void Build(ContentTypePartDefinitionBuilder builder) { + builder.WithSetting("AuditTrailPartSettings.ShowAuditTrailLink", ShowAuditTrailLink.ToString(CultureInfo.InvariantCulture)); + builder.WithSetting("AuditTrailPartSettings.ShowAuditTrail", ShowAuditTrail.ToString(CultureInfo.InvariantCulture)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettingsEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettingsEvents.cs new file mode 100644 index 000000000..f5965c104 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettingsEvents.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Builders; +using Orchard.ContentManagement.MetaData.Models; +using Orchard.ContentManagement.ViewModels; + +namespace Orchard.AuditTrail.Settings { + public class AuditTrailPartSettingsEvents : ContentDefinitionEditorEventsBase { + + public override IEnumerable TypePartEditor(ContentTypePartDefinition definition) { + if (definition.PartDefinition.Name != "AuditTrailPart") + yield break; + + var settings = definition.Settings.GetModel(); + yield return DefinitionTemplate(settings); + } + + public override IEnumerable TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) { + if (builder.Name != "AuditTrailPart") + yield break; + + var settings = new AuditTrailPartSettings(); + updateModel.TryUpdateModel(settings, "AuditTrailPartSettings", null, null); + settings.Build(builder); + + yield return DefinitionTemplate(settings); + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml new file mode 100644 index 000000000..5a6b6995f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml @@ -0,0 +1,15 @@ +@model Orchard.AuditTrail.Settings.AuditTrailPartSettings +
+
+ @Html.CheckBoxFor(m => m.ShowAuditTrailLink) + @Html.LabelFor(m => m.ShowAuditTrailLink, T("Show audit trail link").Text, new { @class = "forcheckbox" }) + @T("Renders a link to the audit trail of the content item.") +
+
+
+
+ @Html.CheckBoxFor(m => m.ShowAuditTrail) + @Html.LabelFor(m => m.ShowAuditTrail, T("Show inline audit trail").Text, new { @class = "forcheckbox" }) + @T("Renders an inline view of the audit trail of the content item.") +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailComment.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml From 79bd8639078570c23b72f0c2aaf50ae3cafe1316 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 25 May 2014 15:52:35 +0200 Subject: [PATCH 005/116] Fixing issue caused by name change. --- .../Views/EditorTemplates/Parts.AuditTrail.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml index fb15345bb..21341bae6 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml @@ -1,4 +1,4 @@ -@model Orchard.AuditTrail.Models.AuditTrailCommentPart +@model Orchard.AuditTrail.Models.AuditTrailPart
@T("Audit Trail")
From 5f63454cee5f52e2e9c24d93878a775603b3bfc2 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 25 May 2014 16:03:30 +0200 Subject: [PATCH 006/116] Improved ordering and added a part setting. --- .../Orchard.AuditTrail/Services/AuditTrailManager.cs | 4 ++-- .../Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs | 2 ++ .../DefinitionTemplates/AuditTrailPartSettings.cshtml | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 2529ac508..54db35ab5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -44,10 +44,10 @@ namespace Orchard.AuditTrail.Services { switch (orderBy) { default: - query = query.OrderByDescending(x => x.CreatedUtc); + query = query.OrderByDescending(x => x.CreatedUtc).ThenByDescending(x => x.Id); break; case AuditTrailOrderBy.EventAscending: - query = query.OrderBy(x => x.Event); + query = query.OrderBy(x => x.Event).ThenByDescending(x => x.Id); break; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs index 8acda67e2..25f9c4a75 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs @@ -5,10 +5,12 @@ namespace Orchard.AuditTrail.Settings { public class AuditTrailPartSettings { public bool ShowAuditTrailLink { get; set; } public bool ShowAuditTrail { get; set; } + public bool ShowAuditTrailCommentInput { get; set; } public void Build(ContentTypePartDefinitionBuilder builder) { builder.WithSetting("AuditTrailPartSettings.ShowAuditTrailLink", ShowAuditTrailLink.ToString(CultureInfo.InvariantCulture)); builder.WithSetting("AuditTrailPartSettings.ShowAuditTrail", ShowAuditTrail.ToString(CultureInfo.InvariantCulture)); + builder.WithSetting("AuditTrailPartSettings.ShowAuditTrailCommentInput", ShowAuditTrailCommentInput.ToString(CultureInfo.InvariantCulture)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml index 5a6b6995f..11a5936ce 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/DefinitionTemplates/AuditTrailPartSettings.cshtml @@ -12,4 +12,11 @@ @Html.LabelFor(m => m.ShowAuditTrail, T("Show inline audit trail").Text, new { @class = "forcheckbox" }) @T("Renders an inline view of the audit trail of the content item.")
+
+
+
+ @Html.CheckBoxFor(m => m.ShowAuditTrailCommentInput) + @Html.LabelFor(m => m.ShowAuditTrailCommentInput, T("Show comment input").Text, new { @class = "forcheckbox" }) + @T("Renders a text field to allow the user to enter a comment about the changes she made.") +
\ No newline at end of file From 780d1248d3c239e932ebdb9479834f9cfe978f6b Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 01:36:05 +0200 Subject: [PATCH 007/116] Implementing inline audit trail on content editor view. --- .../Drivers/AuditTrailPartDriver.cs | 66 +++++++++++++++++-- .../Orchard.AuditTrail.csproj | 4 +- .../Modules/Orchard.AuditTrail/Placement.info | 5 +- .../Scripts/audit-trail-admin.js | 10 +++ .../Views/Admin/Index.cshtml | 6 +- ...cshtml => Parts.AuditTrail.Comment.cshtml} | 3 +- .../Views/Parts.AuditTrail.Link.cshtml | 8 +++ .../Views/Parts.AuditTrail.cshtml | 61 +++++++++++++++++ 8 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/{Parts.AuditTrail.cshtml => Parts.AuditTrail.Comment.cshtml} (81%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 41c332748..7c1cfb1e8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -1,20 +1,72 @@ -using Orchard.AuditTrail.Models; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Settings; +using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; +using Orchard.UI.Navigation; namespace Orchard.AuditTrail.Drivers { public class AuditTrailPartDriver : ContentPartDriver { + private readonly IOrchardServices _services; + private readonly IAuditTrailManager _auditTrailManager; + private readonly IAuditTrailEventDisplayBuilder _displayBuilder; + + public AuditTrailPartDriver(IOrchardServices services, IAuditTrailManager auditTrailManager, IAuditTrailEventDisplayBuilder displayBuilder) { + _services = services; + _auditTrailManager = auditTrailManager; + _displayBuilder = displayBuilder; + } + protected override DriverResult Editor(AuditTrailPart part, dynamic shapeHelper) { return Editor(part, null, shapeHelper); } protected override DriverResult Editor(AuditTrailPart part, IUpdateModel updater, dynamic shapeHelper) { - return ContentShape("Parts_AuditTrail_Edit", () => { - if (updater != null) { - updater.TryUpdateModel(part, Prefix, null, null); - } - return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail", Prefix: Prefix); - }); + var settings = part.Settings.GetModel(); + var results = new List(); + + if (settings.ShowAuditTrailCommentInput) { + results.Add(ContentShape("Parts_AuditTrail_Comment", () => { + if (updater != null) { + updater.TryUpdateModel(part, Prefix, null, null); + } + return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail.Comment", Prefix: Prefix); + })); + } + + if (settings.ShowAuditTrailLink) { + results.Add(ContentShape("Parts_AuditTrail_Link", () => shapeHelper.Parts_AuditTrail_Link())); + } + + if (settings.ShowAuditTrail) { + results.Add(ContentShape("Parts_AuditTrail", () => { + var pager = new Pager(_services.WorkContext.CurrentSite, null, null); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { + FilterKey = "content", + FilterValue = part.Id.ToString(CultureInfo.InvariantCulture) + }); + var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); + var eventDescriptors = from c in _auditTrailManager.Describe() + from e in c.Events + select e; + var recordViewModels = from record in pageOfData + let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) + where descriptor != null + select new AuditTrailEventSummaryViewModel { + Record = record, + EventDescriptor = descriptor, + CategoryDescriptor = descriptor.CategoryDescriptor, + SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") + }; + return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape); + })); + } + + return Combined(results.ToArray()); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index d244f0be3..06898f0e9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -83,6 +83,8 @@ + + @@ -151,7 +153,7 @@ - + 10.0 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info index 99196942a..5f9a1ba88 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -1,5 +1,8 @@  - + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js new file mode 100644 index 000000000..0b8b47007 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js @@ -0,0 +1,10 @@ +(function($) { + // Initialize Expando control + $(".expando-wrapper legend").expandoControl( + function (controller) { + return controller.nextAll(".expando"); + }, { + collapse: true, + remember: true + }); +})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index e973cfbca..d69f6f5a2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -9,6 +9,8 @@ new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.DateDescending}, new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.EventAscending}, }; + + Layout.Title = T("Audit Trail"); }
@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { @@ -17,9 +19,9 @@ @Html.Hidden("filtervalue", Model.Filter.FilterValue) @Html.Label("username", T("User:").Text) @Html.TextBox("username", Model.Filter.UserName, new { @class = "text" }) - @Html.LabelFor(m => from, T("Between:")) + @Html.LabelFor(m => from, T("From:")) @Html.EditorFor(m => from) - @Html.LabelFor(m => to, T("And:")) + @Html.LabelFor(m => to, T("To:")) @Html.EditorFor(m => to) @Html.LabelFor(m => orderBy, T("Ordered by:")) @Html.DropDownListFor(m => orderBy, orderByItems) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml similarity index 81% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml index 21341bae6..ea4d776fa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml @@ -1,8 +1,7 @@ @model Orchard.AuditTrail.Models.AuditTrailPart
- @T("Audit Trail")
- @Html.LabelFor(m => m.Comment) + @Html.LabelFor(m => m.Comment, T("Audit Trail Comment")) @Html.TextBoxFor(m => m.Comment, new { @class = "text large" }) @T("Optionally provide a comment about this change. This comment will be stored as part of an audit trail event.")
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml new file mode 100644 index 000000000..d7549045c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml @@ -0,0 +1,8 @@ +@{ + var contentId = (int)Model.ContentPart.Id; +} +@if (contentId > 0) { +
+ @Html.ActionLink(T("View Audit Trail").Text, "Index", "Admin", new { filterkey = "content", filtervalue = contentId, area = "Orchard.AuditTrail" }, null) +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml new file mode 100644 index 000000000..113ff6f63 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -0,0 +1,61 @@ +@using Orchard.AuditTrail.Models +@using Orchard.AuditTrail.ViewModels +@{ + Script.Require("ShapesBase"); + Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); + Script.Include("audit-trail-admin.js").AtFoot(); +} +@{ + var records = (IEnumerable)Model.Records; + var auditTrailPart = (AuditTrailPart)Model.ContentPart; +} +@if (auditTrailPart.Id > 0) { + +
+ @T("Audit Trail") +
+
+ @if (!records.Any()) { +

@T("There are no audit trail events to display.")

+ } + else { + + + + + + + + + + + + + + @foreach (var record in records) { + + + + + + + + + + } + + @if (Model.Pager.TotalItemCount > Model.Pager.PageSize) { + + + + + + } +
@T("Event")@T("Category")@T("User")@T("Timestamp")@T("Comment")@T("Event Data")
@record.EventDescriptor.Name@record.CategoryDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment@Display(record.SummaryShape)@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
+ @Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { filterKey = "content", filterValue = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null) +
+ } +
+
+
+} From 0e06e3d6a040f3681d76d052ed7da0125263d13c Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 02:00:29 +0200 Subject: [PATCH 008/116] Added User audit trail provider. --- .../Orchard.AuditTrail.csproj | 11 ++++-- .../Content}/AuditTrailEventHandler.cs | 2 +- .../ContentAuditTrailEventProvider.cs | 2 +- .../Content}/GlobalContentHandler.cs | 6 ++-- .../Providers/User/IUserEventHandler.cs | 11 ++++++ .../User/UserAuditTrailEventProvider.cs | 13 +++++++ .../Providers/User/UserEventHandler.cs | 34 +++++++++++++++++++ .../Views/AuditTrailEvent.SummaryAdmin.cshtml | 24 +------------ 8 files changed, 72 insertions(+), 31 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{Handlers => Providers/Content}/AuditTrailEventHandler.cs (92%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{ => Content}/ContentAuditTrailEventProvider.cs (95%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{Handlers => Providers/Content}/GlobalContentHandler.cs (95%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 06898f0e9..a83155146 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -73,6 +73,7 @@ + @@ -100,9 +101,12 @@ - + + + + @@ -114,7 +118,7 @@ - + @@ -122,7 +126,7 @@ - + @@ -155,6 +159,7 @@ + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs similarity index 92% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs index d37ce91dd..a0e334448 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs @@ -2,7 +2,7 @@ using Orchard.AuditTrail.Services; using Orchard.ContentManagement; -namespace Orchard.AuditTrail.Handlers { +namespace Orchard.AuditTrail.Providers.Content { public class AuditTrailEventHandler : IAuditTrailEventHandler { public void Create(AuditTrailCreateContext context) { var content = (IContent)context.Properties["Content"]; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs similarity index 95% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs index 5c3c8c7f5..69239aeda 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs @@ -1,7 +1,7 @@ using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; -namespace Orchard.AuditTrail.Providers { +namespace Orchard.AuditTrail.Providers.Content { public class ContentAuditTrailEventProvider : AuditTrailEventProviderBase { public const string Created = "Created"; public const string Saved = "Saved"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs similarity index 95% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 3c7c415b1..df653fb98 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; -using Orchard.AuditTrail.Providers; +using System.Globalization; using Orchard.AuditTrail.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Records; -namespace Orchard.AuditTrail.Handlers { +namespace Orchard.AuditTrail.Providers.Content { public class GlobalContentHandler : ContentHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; @@ -56,7 +56,7 @@ namespace Orchard.AuditTrail.Handlers { eventData["PreviousContentItemVersionId"] = previousContentItemVersion.Id; } - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString()); + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString(CultureInfo.InvariantCulture)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs new file mode 100644 index 000000000..bf66c0a24 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs @@ -0,0 +1,11 @@ +using Orchard.Events; +using Orchard.Security; + +namespace Orchard.AuditTrail.Providers.User { + public interface IUserEventHandler : IEventHandler { + /// + /// Called after a user has changed password + /// + void ChangedPassword(IUser user); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs new file mode 100644 index 000000000..738874524 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs @@ -0,0 +1,13 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Providers.User { + public class UserAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string PasswordChanged = "PasswordChanged"; + + public override void Describe(DescribeContext context) { + context.For("User", T("User")) + .Event(this, PasswordChanged, T("Password changed"), T("A user's password was changed."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs new file mode 100644 index 000000000..759f319dc --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Globalization; +using Orchard.AuditTrail.Services; +using Orchard.Security; + +namespace Orchard.AuditTrail.Providers.User { + public class UserEventHandler : IUserEventHandler { + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + + public UserEventHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { + _auditTrailManager = auditTrailManager; + _wca = wca; + } + + public void ChangedPassword(IUser user) { + RecordAuditTrail(UserAuditTrailEventProvider.PasswordChanged, user); + } + + private void RecordAuditTrail(string eventName, IUser user) { + + var properties = new Dictionary { + {"User", user} + }; + + var eventData = new Dictionary { + {"UserId", user.Id}, + {"UserName", user.UserName} + }; + + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.Id.ToString(CultureInfo.InvariantCulture)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml index 545e82d63..5f282702b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml @@ -1,23 +1 @@ -@using Orchard.AuditTrail.Models -@{ - var record = (AuditTrailEventRecord)Model.Record; - var detailsUrl = Url.Action("Detail", "Admin", new {id = record.Id, area = "Orchard.AuditTrail"}); -} -
-
-
-
- @record.Event - @record.Category -
- -
-
-
- @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) - @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@record.UserName - } -
-
\ No newline at end of file + \ No newline at end of file From 722a62343560f7a86643c6d4265377b2b84c6b9a Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 02:14:38 +0200 Subject: [PATCH 009/116] Adding default summary admin view for Password Changed event. --- .../Views/AuditTrailEvent-User.SummaryAdmin.cshtml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml new file mode 100644 index 000000000..9a09f35fd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var userName = eventData.Get("UserName"); +} + +
+ @userName +
\ No newline at end of file From 84dae20c8202965bdff36c088b2ffac6e740c1d9 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 02:15:22 +0200 Subject: [PATCH 010/116] Updating project file to include the password changed view. --- .../Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index a83155146..6cb1d6cc4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -86,6 +86,7 @@ +
From f49a5d74f4ff9def372338286a25449ac1383657 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 02:16:32 +0200 Subject: [PATCH 011/116] Improving variable names and executing queries early on for easier debugging. --- .../Orchard.AuditTrail/Controllers/AdminController.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 2e3a76160..02353d50f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -40,11 +40,12 @@ namespace Orchard.AuditTrail.Controllers { To = _dateServices.ConvertFromLocalString(filterParameters.To.Date, filterParameters.To.Time), }, filterParameters.OrderBy); var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var eventDescriptors = from c in _auditTrailManager.Describe() + var eventDescriptorsQuery = from c in _auditTrailManager.Describe() from e in c.Events select e; - var recordViewModels = from record in pageOfData - let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) + var eventDescriptors = eventDescriptorsQuery.ToDictionary(x => x.Event); + var recordViewModelsQuery = from record in pageOfData + let descriptor = eventDescriptors.ContainsKey(record.Event) ? eventDescriptors[record.Event] : default(AuditTrailEventDescriptor) where descriptor != null select new AuditTrailEventSummaryViewModel { Record = record, @@ -54,7 +55,7 @@ namespace Orchard.AuditTrail.Controllers { }; var viewModel = new AuditTrailViewModel { - Records = recordViewModels, + Records = recordViewModelsQuery.ToArray(), Pager = pagerShape, Filter = filterParameters }; From 58ad9671b930ed9dd2d9243bf54f7c22ef6812ab Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 12:01:27 +0200 Subject: [PATCH 012/116] Adding Roles event source to Orchard.Roles [Core Module Change] --- .../Drivers/UserRolesPartDriver.cs | 13 ++++++++++--- .../Orchard.Roles/Events/IRoleEventHandler.cs | 11 +++++++++++ .../Events/PermissionAddedContext.cs | 3 +++ .../Events/PermissionRemovedContext.cs | 3 +++ .../Events/PermissionRoleContext.cs | 7 +++++++ .../Orchard.Roles/Events/RoleContext.cs | 7 +++++++ .../Events/RoleCreatedContext.cs | 3 +++ .../Events/RoleRemovedContext.cs | 3 +++ .../Orchard.Roles/Events/UserAddedContext.cs | 3 +++ .../Events/UserRemovedContext.cs | 3 +++ .../Orchard.Roles/Events/UserRoleContext.cs | 7 +++++++ .../Orchard.Roles/Orchard.Roles.csproj | 10 ++++++++++ .../Orchard.Roles/Services/RoleService.cs | 19 +++++++++++++++---- 13 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionAddedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRemovedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRoleContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/RoleContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/RoleCreatedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRemovedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/UserAddedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/UserRemovedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/UserRoleContext.cs diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Drivers/UserRolesPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Roles/Drivers/UserRolesPartDriver.cs index 43d69d6d8..d92973cb1 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Drivers/UserRolesPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Drivers/UserRolesPartDriver.cs @@ -5,6 +5,7 @@ using Orchard.ContentManagement.Drivers; using Orchard.Data; using Orchard.ContentManagement; using Orchard.Localization; +using Orchard.Roles.Events; using Orchard.Roles.Models; using Orchard.Roles.Services; using Orchard.Roles.ViewModels; @@ -19,6 +20,7 @@ namespace Orchard.Roles.Drivers { private readonly INotifier _notifier; private readonly IAuthenticationService _authenticationService; private readonly IAuthorizationService _authorizationService; + private readonly IRoleEventHandler _roleEventHandlers; private const string TemplateName = "Parts/Roles.UserRoles"; public UserRolesPartDriver( @@ -26,12 +28,15 @@ namespace Orchard.Roles.Drivers { IRoleService roleService, INotifier notifier, IAuthenticationService authenticationService, - IAuthorizationService authorizationService) { + IAuthorizationService authorizationService, + IRoleEventHandler roleEventHandlers) { + _userRolesRepository = userRolesRepository; _roleService = roleService; _notifier = notifier; _authenticationService = authenticationService; _authorizationService = authorizationService; + _roleEventHandlers = roleEventHandlers; T = NullLocalizer.Instance; } @@ -70,16 +75,18 @@ namespace Orchard.Roles.Drivers { var model = BuildEditorViewModel(userRolesPart); if (updater.TryUpdateModel(model, Prefix, null, null)) { - var currentUserRoleRecords = _userRolesRepository.Fetch(x => x.UserId == model.User.Id); + var currentUserRoleRecords = _userRolesRepository.Fetch(x => x.UserId == model.User.Id).ToArray(); var currentRoleRecords = currentUserRoleRecords.Select(x => x.Role); - var targetRoleRecords = model.Roles.Where(x => x.Granted).Select(x => _roleService.GetRole(x.RoleId)); + var targetRoleRecords = model.Roles.Where(x => x.Granted).Select(x => _roleService.GetRole(x.RoleId)).ToArray(); foreach (var addingRole in targetRoleRecords.Where(x => !currentRoleRecords.Contains(x))) { _notifier.Warning(T("Adding role {0} to user {1}", addingRole.Name, userRolesPart.As().UserName)); _userRolesRepository.Create(new UserRolesPartRecord { UserId = model.User.Id, Role = addingRole }); + _roleEventHandlers.UserAdded(new UserAddedContext {Role = addingRole, User = model.User}); } foreach (var removingRole in currentUserRoleRecords.Where(x => !targetRoleRecords.Contains(x.Role))) { _notifier.Warning(T("Removing role {0} from user {1}", removingRole.Role.Name, userRolesPart.As().UserName)); _userRolesRepository.Delete(removingRole); + _roleEventHandlers.UserRemoved(new UserRemovedContext { Role = removingRole.Role, User = model.User }); } } return ContentShape("Parts_Roles_UserRoles_Edit", diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs new file mode 100644 index 000000000..54ace745a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs @@ -0,0 +1,11 @@ +using Orchard.Events; + +namespace Orchard.Roles.Events { + public interface IRoleEventHandler : IEventHandler { + void Created(RoleCreatedContext context); + void Removed(RoleRemovedContext context); + void PermissionsChanged(PermissionAddedContext context); + void UserAdded(UserAddedContext context); + void UserRemoved(UserRemovedContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionAddedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionAddedContext.cs new file mode 100644 index 000000000..feb719a6d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionAddedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class PermissionAddedContext : PermissionRoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRemovedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRemovedContext.cs new file mode 100644 index 000000000..dbea26acc --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRemovedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class PermissionRemovedContext : PermissionRoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRoleContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRoleContext.cs new file mode 100644 index 000000000..9845f8ccc --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/PermissionRoleContext.cs @@ -0,0 +1,7 @@ +using Orchard.Roles.Models; + +namespace Orchard.Roles.Events { + public class PermissionRoleContext : RoleContext { + public PermissionRecord Permission { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleContext.cs new file mode 100644 index 000000000..a5ddcd461 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleContext.cs @@ -0,0 +1,7 @@ +using Orchard.Roles.Models; + +namespace Orchard.Roles.Events { + public class RoleContext { + public RoleRecord Role { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleCreatedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleCreatedContext.cs new file mode 100644 index 000000000..69cc800d9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleCreatedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class RoleCreatedContext : RoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRemovedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRemovedContext.cs new file mode 100644 index 000000000..cb4e22af1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRemovedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class RoleRemovedContext : RoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/UserAddedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserAddedContext.cs new file mode 100644 index 000000000..955df1602 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserAddedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class UserAddedContext : UserRoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRemovedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRemovedContext.cs new file mode 100644 index 000000000..ae26444f3 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRemovedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.Roles.Events { + public class UserRemovedContext : UserRoleContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRoleContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRoleContext.cs new file mode 100644 index 000000000..cf1e47e99 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/UserRoleContext.cs @@ -0,0 +1,7 @@ +using Orchard.Security; + +namespace Orchard.Roles.Events { + public class UserRoleContext : RoleContext { + public IUser User { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj index 7d9f72b12..ca4d4efd5 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj +++ b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj @@ -72,6 +72,16 @@ + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs index f39851411..7eb10e530 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs @@ -6,6 +6,7 @@ using Orchard.Caching; using Orchard.Data; using Orchard.Localization; using Orchard.Logging; +using Orchard.Roles.Events; using Orchard.Roles.Models; using Orchard.Security.Permissions; @@ -20,6 +21,7 @@ namespace Orchard.Roles.Services { private readonly IEnumerable _permissionProviders; private readonly ICacheManager _cacheManager; private readonly ISignals _signals; + private readonly IRoleEventHandler _roleEventHandlers; public RoleService( IRepository roleRepository, @@ -27,14 +29,16 @@ namespace Orchard.Roles.Services { IRepository userRolesRepository, IEnumerable permissionProviders, ICacheManager cacheManager, - ISignals signals - ) { + ISignals signals, + IRoleEventHandler roleEventHandlers) { + _roleRepository = roleRepository; _permissionRepository = permissionRepository; _userRolesRepository = userRolesRepository; _permissionProviders = permissionProviders; _cacheManager = cacheManager; _signals = signals; + _roleEventHandlers = roleEventHandlers; Logger = NullLogger.Instance; T = NullLocalizer.Instance; } @@ -59,7 +63,9 @@ namespace Orchard.Roles.Services { if (GetRoleByName(roleName) != null) return; - _roleRepository.Create(new RoleRecord { Name = roleName }); + var roleRecord = new RoleRecord {Name = roleName}; + _roleRepository.Create(roleRecord); + _roleEventHandlers.Created(new RoleCreatedContext { Role = roleRecord }); TriggerSignal(); } @@ -74,7 +80,9 @@ namespace Orchard.Roles.Services { RoleRecord roleRecord = GetRoleByName(roleName); PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permissionName); roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord }); + _roleEventHandlers.PermissionsChanged(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); TriggerSignal(); + } public void UpdateRole(int id, string roleName, IEnumerable rolePermissions) { @@ -92,6 +100,7 @@ namespace Orchard.Roles.Services { } PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permission); roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord }); + _roleEventHandlers.PermissionsChanged(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); } TriggerSignal(); } @@ -125,7 +134,9 @@ namespace Orchard.Roles.Services { _userRolesRepository.Delete(userRoleRecord); } - _roleRepository.Delete(GetRole(id)); + var roleRecord = GetRole(id); + _roleRepository.Delete(roleRecord); + _roleEventHandlers.Removed(new RoleRemovedContext { Role = roleRecord}); TriggerSignal(); } From 80a27b04a7bb94d5bbdfedbdca00dea29b3c872d Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 14:18:55 +0200 Subject: [PATCH 013/116] Adding role renamed event. [Core Module Change] --- .../Modules/Orchard.Roles/Events/IRoleEventHandler.cs | 1 + .../Modules/Orchard.Roles/Events/RoleRenamedContext.cs | 6 ++++++ .../Modules/Orchard.Roles/Orchard.Roles.csproj | 1 + .../Modules/Orchard.Roles/Services/RoleService.cs | 8 +++++++- 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRenamedContext.cs diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs index 54ace745a..ce8206f84 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs @@ -4,6 +4,7 @@ namespace Orchard.Roles.Events { public interface IRoleEventHandler : IEventHandler { void Created(RoleCreatedContext context); void Removed(RoleRemovedContext context); + void Renamed(RoleRenamedContext context); void PermissionsChanged(PermissionAddedContext context); void UserAdded(UserAddedContext context); void UserRemoved(UserRemovedContext context); diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRenamedContext.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRenamedContext.cs new file mode 100644 index 000000000..204a7ebd7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/RoleRenamedContext.cs @@ -0,0 +1,6 @@ +namespace Orchard.Roles.Events { + public class RoleRenamedContext : RoleContext { + public string PreviousRoleName { get; set; } + public string NewRoleName { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj index ca4d4efd5..59af60d86 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj +++ b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj @@ -79,6 +79,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs index 7eb10e530..6e38a455c 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs @@ -86,9 +86,15 @@ namespace Orchard.Roles.Services { } public void UpdateRole(int id, string roleName, IEnumerable rolePermissions) { - RoleRecord roleRecord = GetRole(id); + var roleRecord = GetRole(id); + var currentRoleName = roleRecord.Name; roleRecord.Name = roleName; roleRecord.RolesPermissions.Clear(); + + if (!String.Equals(currentRoleName, roleName)) { + _roleEventHandlers.Renamed(new RoleRenamedContext {Role = roleRecord, NewRoleName = roleName, PreviousRoleName = currentRoleName}); + } + foreach (var rolePermission in rolePermissions) { string permission = rolePermission; if (_permissionRepository.Get(x => x.Name == permission) == null) { From 87d01105def7f3f6e6e016c8acec6bfe0cee7320 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 14:42:44 +0200 Subject: [PATCH 014/116] Improved role permission events. [Core Module Change] --- .../Orchard.Roles/Events/IRoleEventHandler.cs | 3 ++- .../Modules/Orchard.Roles/Services/RoleService.cs | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs index ce8206f84..fb3a3ccaa 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Events/IRoleEventHandler.cs @@ -5,7 +5,8 @@ namespace Orchard.Roles.Events { void Created(RoleCreatedContext context); void Removed(RoleRemovedContext context); void Renamed(RoleRenamedContext context); - void PermissionsChanged(PermissionAddedContext context); + void PermissionAdded(PermissionAddedContext context); + void PermissionRemoved(PermissionRemovedContext context); void UserAdded(UserAddedContext context); void UserRemoved(UserRemovedContext context); } diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs index 6e38a455c..a5fde2127 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Services/RoleService.cs @@ -80,7 +80,7 @@ namespace Orchard.Roles.Services { RoleRecord roleRecord = GetRoleByName(roleName); PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permissionName); roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord }); - _roleEventHandlers.PermissionsChanged(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); + _roleEventHandlers.PermissionAdded(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); TriggerSignal(); } @@ -88,6 +88,7 @@ namespace Orchard.Roles.Services { public void UpdateRole(int id, string roleName, IEnumerable rolePermissions) { var roleRecord = GetRole(id); var currentRoleName = roleRecord.Name; + var currentPermissions = roleRecord.RolesPermissions.ToDictionary(x => x.Permission.Name); roleRecord.Name = roleName; roleRecord.RolesPermissions.Clear(); @@ -106,8 +107,17 @@ namespace Orchard.Roles.Services { } PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permission); roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord }); - _roleEventHandlers.PermissionsChanged(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); + + if(!currentPermissions.ContainsKey(permission)) + _roleEventHandlers.PermissionAdded(new PermissionAddedContext { Role = roleRecord, Permission = permissionRecord }); + else { + currentPermissions.Remove(permission); + } } + + foreach(var permission in currentPermissions.Values) + _roleEventHandlers.PermissionRemoved(new PermissionRemovedContext { Role = roleRecord, Permission = permission.Permission }); + TriggerSignal(); } From a6a31914225fe1d6d37e45d0af02b154f06ea1ab Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 26 May 2014 14:44:18 +0200 Subject: [PATCH 015/116] Implementing Role audit trail events. --- .../Modules/Orchard.AuditTrail/Module.txt | 3 +- .../Orchard.AuditTrail.csproj | 7 ++ .../Content/AuditTrailEventHandler.cs | 2 +- .../Providers/Role/IRoleEventHandler.cs | 13 +++ .../Role/RoleAuditTrailEventProvider.cs | 25 ++++++ .../Providers/Role/RoleEventHandler.cs | 85 +++++++++++++++++++ .../Services/AuditTrailEventDisplayBuilder.cs | 9 +- ...t-Role-PermissionAdded.SummaryAdmin.cshtml | 10 +++ ...Role-PermissionRemoved.SummaryAdmin.cshtml | 10 +++ ...Event-Role-RoleCreated.SummaryAdmin.cshtml | 9 ++ ...Event-Role-RoleRenamed.SummaryAdmin.cshtml | 10 +++ .../Views/AuditTrailEvent.SummaryAdmin.cshtml | 4 +- 12 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index f5f8bd196..2817a7e3b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -9,4 +9,5 @@ Features: Orchard.AuditTrail: Name: AuditTrail Description: Provides the core audit trail framework. - Category: Security \ No newline at end of file + Category: Security + Dependencies: Orchard.Users, Orchard.Roles \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 6cb1d6cc4..a936c5b63 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -87,6 +87,10 @@ + + + + @@ -105,6 +109,9 @@ + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs index a0e334448..7fa9130a2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs @@ -5,7 +5,7 @@ using Orchard.ContentManagement; namespace Orchard.AuditTrail.Providers.Content { public class AuditTrailEventHandler : IAuditTrailEventHandler { public void Create(AuditTrailCreateContext context) { - var content = (IContent)context.Properties["Content"]; + var content = context.Properties.ContainsKey("Content") ? (IContent)context.Properties["Content"] : default(IContent); var auditTrailPart = content != null ? content.As() : default(AuditTrailPart); if (auditTrailPart == null) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs new file mode 100644 index 000000000..40450a452 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs @@ -0,0 +1,13 @@ +using Orchard.Events; + +namespace Orchard.AuditTrail.Providers.Role { + public interface IRoleEventHandler : IEventHandler { + void Created(dynamic context); + void Removed(dynamic context); + void Renamed(dynamic context); + void PermissionAdded(dynamic context); + void PermissionRemoved(dynamic context); + void UserAdded(dynamic context); + void UserRemoved(dynamic context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs new file mode 100644 index 000000000..78ffafb58 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs @@ -0,0 +1,25 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Providers.Role { + public class RoleAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string RoleCreated = "RoleCreated"; + public const string RoleRemoved = "RoleRemoved"; + public const string RoleRenamed = "RoleRenamed"; + public const string PermissionAdded = "PermissionAdded"; + public const string PermissionRemoved = "PermissionRemoved"; + public const string UserAdded = "UserAdded"; + public const string UserRemoved = "UserRemoved"; + + public override void Describe(DescribeContext context) { + context.For("Role", T("Role")) + .Event(this, RoleCreated, T("Role created"), T("A role was created."), enableByDefault: true) + .Event(this, RoleRemoved, T("Role removed"), T("A role was removed."), enableByDefault: true) + .Event(this, RoleRenamed, T("Role renamed"), T("A role was renamed."), enableByDefault: true) + .Event(this, PermissionAdded, T("Permission added"), T("Permission was added to a role."), enableByDefault: true) + .Event(this, PermissionRemoved, T("Permission removed"), T("Permission was removed from a role."), enableByDefault: true) + .Event(this, UserAdded, T("User added"), T("A user was added to a role."), enableByDefault: true) + .Event(this, UserRemoved, T("User removed"), T("A user was removed from a role."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs new file mode 100644 index 000000000..6d91bad1a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Services; +using Orchard.Security; + +namespace Orchard.AuditTrail.Providers.Role { + public class RoleEventHandler : IRoleEventHandler { + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + + public RoleEventHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { + _auditTrailManager = auditTrailManager; + _wca = wca; + } + + public void Created(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.RoleCreated, context.Role.Name); + } + + public void Removed(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.RoleRemoved, context.Role.Name); + } + + public void Renamed(dynamic context) { + var eventData = new Dictionary { + {"RoleName", (string)context.Role.Name}, + {"PreviousRoleName", (string)context.PreviousRoleName}, + {"NewRoleName", (string)context.NewRoleName}, + }; + + RecordAuditTrail(RoleAuditTrailEventProvider.RoleRenamed, context.Role.Name, properties: null, eventData:eventData); + } + + public void PermissionAdded(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.PermissionAdded, context.Role.Name, context.Permission.Name); + } + + public void PermissionRemoved(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.PermissionRemoved, context.Role.Name, context.Permission.Name); + } + + public void UserAdded(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.UserAdded, context.Role.Name, context.User); + } + + public void UserRemoved(dynamic context) { + RecordAuditTrail(RoleAuditTrailEventProvider.UserRemoved, context.Role.Name, context.User); + } + + private void RecordAuditTrail(string eventName, string roleName) { + var eventData = new Dictionary { + {"RoleName", roleName} + }; + + RecordAuditTrail(eventName, roleName, properties: null, eventData: eventData); + } + + private void RecordAuditTrail(string eventName, string roleName, string permissionName) { + var eventData = new Dictionary { + {"RoleName", roleName}, + {"PermissionName", permissionName} + }; + + RecordAuditTrail(eventName, roleName, properties: null, eventData: eventData); + } + + + private void RecordAuditTrail(string eventName, string roleName, IUser user) { + + var properties = new Dictionary { + {"User", user} + }; + + var eventData = new Dictionary { + {"RoleName", roleName}, + {"UserName", user.UserName} + }; + + RecordAuditTrail(eventName, roleName, properties, eventData); + } + + private void RecordAuditTrail(string eventName, string roleName, IDictionary properties, IDictionary eventData) { + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "role", eventFilterData: roleName); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs index dd08d9142..fa06f7752 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -25,9 +25,14 @@ namespace Orchard.AuditTrail.Services { metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, record.Event)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, record.Event)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, GetShortName(record.Event))); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, GetShortName(record.Event))); return auditTrailEventShape; } + + private string GetShortName(string fullyQualifiedEventName) { + var index = fullyQualifiedEventName.LastIndexOf('.') + 1; + return fullyQualifiedEventName.Substring(index); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml new file mode 100644 index 000000000..764446ae2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); + var permissionName = eventData.Get("PermissionName"); +} + +
+ @T("Added the {0} permission to the {1} role.", permissionName, roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml new file mode 100644 index 000000000..870bf00f5 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); + var permissionName = eventData.Get("PermissionName"); +} + +
+ @T("Removed the {0} permission from the {1} role.", permissionName, roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml new file mode 100644 index 000000000..91d579147 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); +} + +
+ @T("Created {0} role.", roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml new file mode 100644 index 000000000..8611bd024 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var previousRoleName = eventData.Get("PreviousRoleName"); + var newRoleName = eventData.Get("NewRoleName"); +} + +
+ @T("Renamed {0} to {1}.", previousRoleName, newRoleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml index 5f282702b..ff029a741 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml @@ -1 +1,3 @@ - \ No newline at end of file +@{ + var model = Model; +} \ No newline at end of file From 0acc0b94dab8e1f025c155ac64ced499a06e6b49 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Tue, 27 May 2014 18:30:08 +0200 Subject: [PATCH 016/116] Infusing Orchard.ContentTypes with event sources. [Core Module Change] --- .../Events/ContentFieldAttachedContext.cs | 6 +++ .../Events/ContentFieldDetachedContext.cs | 3 ++ .../Events/ContentPartAttachedContext.cs | 3 ++ .../Events/ContentPartContext.cs | 7 +++ .../Events/ContentPartCreatedContext.cs | 3 ++ .../Events/ContentPartDetachedContext.cs | 3 ++ .../Events/ContentPartFieldContext.cs | 8 +++ .../Events/ContentPartRemovedContext.cs | 3 ++ .../Events/ContentTypeContext.cs | 7 +++ .../Events/ContentTypeCreatedContext.cs | 3 ++ .../Events/ContentTypePartContext.cs | 6 +++ .../Events/ContentTypeRemovedContext.cs | 3 ++ .../Events/IContentDefinitionEventHandler.cs | 14 +++++ .../Orchard.ContentTypes.csproj | 13 +++++ .../Services/ContentDefinitionService.cs | 52 +++++++++++++------ .../Builders/ContentPartDefinitionBuilder.cs | 12 ++++- .../ContentPartFieldDefinitionBuilder.cs | 1 + .../Builders/ContentTypeDefinitionBuilder.cs | 2 + .../ContentTypePartDefinitionBuilder.cs | 2 + 19 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldAttachedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldDetachedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartAttachedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartCreatedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartDetachedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartFieldContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartRemovedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeCreatedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypePartContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeRemovedContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentTypes/Events/IContentDefinitionEventHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldAttachedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldAttachedContext.cs new file mode 100644 index 000000000..a89ae3483 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldAttachedContext.cs @@ -0,0 +1,6 @@ +namespace Orchard.ContentTypes.Events { + public class ContentFieldAttachedContext : ContentPartFieldContext { + public string ContentFieldTypeName { get; set; } + public string ContentFieldDisplayName { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldDetachedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldDetachedContext.cs new file mode 100644 index 000000000..9a3f061ce --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentFieldDetachedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentFieldDetachedContext : ContentPartFieldContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartAttachedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartAttachedContext.cs new file mode 100644 index 000000000..08c9c07e9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartAttachedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentPartAttachedContext : ContentTypePartContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartContext.cs new file mode 100644 index 000000000..b372548d8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartContext.cs @@ -0,0 +1,7 @@ +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentTypes.Events { + public class ContentPartContext { + public ContentPartDefinition ContentPartDefinition { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartCreatedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartCreatedContext.cs new file mode 100644 index 000000000..9ef896a5e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartCreatedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentPartCreatedContext : ContentPartContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartDetachedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartDetachedContext.cs new file mode 100644 index 000000000..bd8435b72 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartDetachedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentPartDetachedContext : ContentTypePartContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartFieldContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartFieldContext.cs new file mode 100644 index 000000000..cf8484d39 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartFieldContext.cs @@ -0,0 +1,8 @@ +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentTypes.Events { + public class ContentPartFieldContext { + public string ContentPartName{ get; set; } + public string ContentFieldName { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartRemovedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartRemovedContext.cs new file mode 100644 index 000000000..0111dc12e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentPartRemovedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentPartRemovedContext : ContentPartContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeContext.cs new file mode 100644 index 000000000..dea46bc45 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeContext.cs @@ -0,0 +1,7 @@ +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentTypes.Events { + public class ContentTypeContext { + public ContentTypeDefinition ContentTypeDefinition { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeCreatedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeCreatedContext.cs new file mode 100644 index 000000000..e502f830b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeCreatedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentTypeCreatedContext : ContentTypeContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypePartContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypePartContext.cs new file mode 100644 index 000000000..e00f1794c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypePartContext.cs @@ -0,0 +1,6 @@ +namespace Orchard.ContentTypes.Events { + public class ContentTypePartContext { + public string ContentTypeName { get; set; } + public string ContentPartName { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeRemovedContext.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeRemovedContext.cs new file mode 100644 index 000000000..5dc2b326d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/ContentTypeRemovedContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.ContentTypes.Events { + public class ContentTypeRemovedContext : ContentTypeContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/IContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/IContentDefinitionEventHandler.cs new file mode 100644 index 000000000..a528a48ad --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Events/IContentDefinitionEventHandler.cs @@ -0,0 +1,14 @@ +using Orchard.Events; + +namespace Orchard.ContentTypes.Events { + public interface IContentDefinitionEventHandler : IEventHandler { + void ContentTypeCreated(ContentTypeCreatedContext context); + void ContentTypeRemoved(ContentTypeRemovedContext context); + void ContentPartCreated(ContentPartCreatedContext context); + void ContentPartRemoved(ContentPartRemovedContext context); + void ContentPartAttached(ContentPartAttachedContext context); + void ContentPartDetached(ContentPartDetachedContext context); + void ContentFieldAttached(ContentFieldAttachedContext context); + void ContentFieldDetached(ContentFieldDetachedContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj index 4bb17849e..f5d713ec7 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj @@ -65,6 +65,19 @@
+ + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs index 51a42cc4f..3fd59f169 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs @@ -5,6 +5,7 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Models; +using Orchard.ContentTypes.Events; using Orchard.ContentTypes.ViewModels; using Orchard.Core.Contents.Extensions; using Orchard.Localization; @@ -16,19 +17,22 @@ namespace Orchard.ContentTypes.Services { private readonly IEnumerable _contentPartDrivers; private readonly IEnumerable _contentFieldDrivers; private readonly IContentDefinitionEditorEvents _contentDefinitionEditorEvents; + private readonly IContentDefinitionEventHandler _contentDefinitionEventHandlers; public ContentDefinitionService( IOrchardServices services, IContentDefinitionManager contentDefinitionManager, IEnumerable contentPartDrivers, IEnumerable contentFieldDrivers, - IContentDefinitionEditorEvents contentDefinitionEditorEvents) - { + IContentDefinitionEditorEvents contentDefinitionEditorEvents, + IContentDefinitionEventHandler contentDefinitionEventHandlers) { + Services = services; _contentDefinitionManager = contentDefinitionManager; _contentPartDrivers = contentPartDrivers; _contentFieldDrivers = contentFieldDrivers; _contentDefinitionEditorEvents = contentDefinitionEditorEvents; + _contentDefinitionEventHandlers = contentDefinitionEventHandlers; T = NullLocalizer.Instance; } @@ -83,8 +87,8 @@ namespace Orchard.ContentTypes.Services { var contentTypeDefinition = new ContentTypeDefinition(name, displayName); _contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition); - _contentDefinitionManager.AlterTypeDefinition(name, - cfg => cfg.Creatable().Draftable()); + _contentDefinitionManager.AlterTypeDefinition(name, cfg => cfg.Creatable().Draftable()); + _contentDefinitionEventHandlers.ContentTypeCreated(new ContentTypeCreatedContext { ContentTypeDefinition = contentTypeDefinition}); return contentTypeDefinition; } @@ -169,15 +173,17 @@ namespace Orchard.ContentTypes.Services { Services.ContentManager.Remove(contentItem); } } - + _contentDefinitionEventHandlers.ContentTypeRemoved(new ContentTypeRemovedContext { ContentTypeDefinition = typeDefinition }); } public void AddPartToType(string partName, string typeName) { _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.WithPart(partName)); + _contentDefinitionEventHandlers.ContentPartAttached(new ContentPartAttachedContext { ContentTypeName = typeName, ContentPartName = partName}); } public void RemovePartFromType(string partName, string typeName) { _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.RemovePart(partName)); + _contentDefinitionEventHandlers.ContentPartDetached(new ContentPartDetachedContext {ContentTypeName = typeName, ContentPartName = partName}); } public IEnumerable GetParts(bool metadataPartsOnly) { @@ -191,8 +197,8 @@ namespace Orchard.ContentTypes.Services { .Select(cpd => new EditPartViewModel(cpd)); // code-defined parts - var codeDefinedParts = metadataPartsOnly ? - Enumerable.Empty() : + var codeDefinedParts = metadataPartsOnly ? + Enumerable.Empty() : _contentPartDrivers.SelectMany(d => d.GetPartInfo().Where(cpd => !userContentParts.Any(m => m.Name == cpd.PartName)).Select(cpi => new EditPartViewModel { Name = cpi.PartName })); // Order by display name @@ -220,7 +226,9 @@ namespace Orchard.ContentTypes.Services { if (!String.IsNullOrEmpty(name)) { _contentDefinitionManager.AlterPartDefinition(name, builder => builder.Attachable()); - return new EditPartViewModel(_contentDefinitionManager.GetPartDefinition(name)); + var partDefinition = _contentDefinitionManager.GetPartDefinition(name); + _contentDefinitionEventHandlers.ContentPartCreated(new ContentPartCreatedContext {ContentPartDefinition = partDefinition}); + return new EditPartViewModel(partDefinition); } return null; @@ -236,11 +244,12 @@ namespace Orchard.ContentTypes.Services { public void RemovePart(string name) { var partDefinition = _contentDefinitionManager.GetPartDefinition(name); var fieldDefinitions = partDefinition.Fields.ToArray(); - foreach(var fieldDefinition in fieldDefinitions) { + foreach (var fieldDefinition in fieldDefinitions) { RemoveFieldFromPart(fieldDefinition.Name, name); } - + _contentDefinitionManager.DeletePartDefinition(name); + _contentDefinitionEventHandlers.ContentPartRemoved(new ContentPartRemovedContext {ContentPartDefinition = partDefinition}); } public IEnumerable GetFields() { @@ -258,10 +267,21 @@ namespace Orchard.ContentTypes.Services { } _contentDefinitionManager.AlterPartDefinition(partName, partBuilder => partBuilder.WithField(fieldName, fieldBuilder => fieldBuilder.OfType(fieldTypeName).WithDisplayName(displayName))); + + _contentDefinitionEventHandlers.ContentFieldAttached(new ContentFieldAttachedContext { + ContentPartName = partName, + ContentFieldTypeName = fieldTypeName, + ContentFieldName = fieldName, + ContentFieldDisplayName = displayName + }); } public void RemoveFieldFromPart(string fieldName, string partName) { _contentDefinitionManager.AlterPartDefinition(partName, typeBuilder => typeBuilder.RemoveField(fieldName)); + _contentDefinitionEventHandlers.ContentFieldDetached(new ContentFieldDetachedContext { + ContentPartName = partName, + ContentFieldName = fieldName + }); } public string GenerateContentTypeNameFromDisplayName(string displayName) { @@ -279,23 +299,23 @@ namespace Orchard.ContentTypes.Services { var part = _contentDefinitionManager.GetPartDefinition(partName); displayName = displayName.ToSafeName(); - if(part == null) { + if (part == null) { var type = _contentDefinitionManager.GetTypeDefinition(partName); - if(type == null) { + if (type == null) { throw new ArgumentException("The part doesn't exist: " + partName); } var typePart = type.Parts.FirstOrDefault(x => x.PartDefinition.Name == partName); - + // id passed in might be that of a type w/ no implicit field - if(typePart == null) { + if (typePart == null) { return displayName; } else { - fieldDefinitions = typePart.PartDefinition.Fields.ToArray(); + fieldDefinitions = typePart.PartDefinition.Fields.ToArray(); } - + } else { fieldDefinitions = part.Fields.ToArray(); diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs index 0f874af11..6fd9a0853 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs @@ -6,6 +6,7 @@ using Orchard.ContentManagement.MetaData.Models; namespace Orchard.ContentManagement.MetaData.Builders { public class ContentPartDefinitionBuilder { + private readonly ContentPartDefinition _part; private string _name; private readonly IList _fields; private readonly SettingsDictionary _settings; @@ -15,6 +16,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { } public ContentPartDefinitionBuilder(ContentPartDefinition existing) { + _part = existing; if (existing == null) { _fields = new List(); _settings = new SettingsDictionary(); @@ -66,7 +68,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { else { existingField = new ContentPartFieldDefinition(fieldName); } - var configurer = new FieldConfigurerImpl(existingField); + var configurer = new FieldConfigurerImpl(existingField, _part); configuration(configurer); _fields.Add(configurer.Build()); return this; @@ -74,12 +76,14 @@ namespace Orchard.ContentManagement.MetaData.Builders { class FieldConfigurerImpl : ContentPartFieldDefinitionBuilder { private ContentFieldDefinition _fieldDefinition; + private readonly ContentPartDefinition _partDefinition; private readonly string _fieldName; - public FieldConfigurerImpl(ContentPartFieldDefinition field) + public FieldConfigurerImpl(ContentPartFieldDefinition field, ContentPartDefinition part) : base(field) { _fieldDefinition = field.FieldDefinition; _fieldName = field.Name; + _partDefinition = part; } public ContentPartFieldDefinition Build() { @@ -94,6 +98,10 @@ namespace Orchard.ContentManagement.MetaData.Builders { get { return _fieldDefinition.Name; } } + public override string PartName { + get { return _partDefinition.Name; } + } + public override ContentPartFieldDefinitionBuilder OfType(ContentFieldDefinition fieldDefinition) { _fieldDefinition = fieldDefinition; return this; diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs index 0000d2698..f975cbbc1 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs @@ -21,6 +21,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { public abstract string Name { get; } public abstract string FieldType { get; } + public abstract string PartName { get; } public abstract ContentPartFieldDefinitionBuilder OfType(ContentFieldDefinition fieldDefinition); public abstract ContentPartFieldDefinitionBuilder OfType(string fieldType); diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs index 8092f7dd7..7b7199139 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs @@ -27,6 +27,8 @@ namespace Orchard.ContentManagement.MetaData.Builders { } } + public string Name { get { return _name; } } + public ContentTypeDefinition Build() { return new ContentTypeDefinition(_name, _displayName, _parts, _settings); } diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs index 04c2d008e..35b73008e 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs @@ -7,10 +7,12 @@ namespace Orchard.ContentManagement.MetaData.Builders { protected ContentTypePartDefinitionBuilder(ContentTypePartDefinition part) { Name = part.PartDefinition.Name; + TypeName = part.ContentTypeDefinition != null ? part.ContentTypeDefinition.Name : default(string); _settings = new SettingsDictionary(part.Settings.ToDictionary(kv => kv.Key, kv => kv.Value)); } public string Name { get; private set; } + public string TypeName { get; private set; } public ContentTypePartDefinitionBuilder WithSetting(string name, string value) { _settings[name] = value; From 6bb121edf6bae52f04b6f23fad86d6eec0a4a35d Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Tue, 27 May 2014 18:31:05 +0200 Subject: [PATCH 017/116] Simplifying Role audit trail event names. --- .../Providers/Role/RoleAuditTrailEventProvider.cs | 12 ++++++------ .../Providers/Role/RoleEventHandler.cs | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs index 78ffafb58..8f7a921a7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs @@ -3,9 +3,9 @@ using Orchard.AuditTrail.Services; namespace Orchard.AuditTrail.Providers.Role { public class RoleAuditTrailEventProvider : AuditTrailEventProviderBase { - public const string RoleCreated = "RoleCreated"; - public const string RoleRemoved = "RoleRemoved"; - public const string RoleRenamed = "RoleRenamed"; + public const string Created = "Created"; + public const string Removed = "Removed"; + public const string Renamed = "Renamed"; public const string PermissionAdded = "PermissionAdded"; public const string PermissionRemoved = "PermissionRemoved"; public const string UserAdded = "UserAdded"; @@ -13,9 +13,9 @@ namespace Orchard.AuditTrail.Providers.Role { public override void Describe(DescribeContext context) { context.For("Role", T("Role")) - .Event(this, RoleCreated, T("Role created"), T("A role was created."), enableByDefault: true) - .Event(this, RoleRemoved, T("Role removed"), T("A role was removed."), enableByDefault: true) - .Event(this, RoleRenamed, T("Role renamed"), T("A role was renamed."), enableByDefault: true) + .Event(this, Created, T("Created"), T("A role was created."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("A role was removed."), enableByDefault: true) + .Event(this, Renamed, T("Renamed"), T("A role was renamed."), enableByDefault: true) .Event(this, PermissionAdded, T("Permission added"), T("Permission was added to a role."), enableByDefault: true) .Event(this, PermissionRemoved, T("Permission removed"), T("Permission was removed from a role."), enableByDefault: true) .Event(this, UserAdded, T("User added"), T("A user was added to a role."), enableByDefault: true) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs index 6d91bad1a..6ff66aa00 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs @@ -13,11 +13,11 @@ namespace Orchard.AuditTrail.Providers.Role { } public void Created(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.RoleCreated, context.Role.Name); + RecordAuditTrail(RoleAuditTrailEventProvider.Created, context.Role.Name); } public void Removed(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.RoleRemoved, context.Role.Name); + RecordAuditTrail(RoleAuditTrailEventProvider.Removed, context.Role.Name); } public void Renamed(dynamic context) { @@ -27,7 +27,7 @@ namespace Orchard.AuditTrail.Providers.Role { {"NewRoleName", (string)context.NewRoleName}, }; - RecordAuditTrail(RoleAuditTrailEventProvider.RoleRenamed, context.Role.Name, properties: null, eventData:eventData); + RecordAuditTrail(RoleAuditTrailEventProvider.Renamed, context.Role.Name, properties: null, eventData:eventData); } public void PermissionAdded(dynamic context) { From 3fe5242dfdba038c5453c58918b321babf3f7d12 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Tue, 27 May 2014 18:32:04 +0200 Subject: [PATCH 018/116] Implementing a ContentType/Part audit trail event provider. --- .../Modules/Orchard.AuditTrail/Module.txt | 2 +- .../Orchard.AuditTrail.csproj | 17 ++++ .../ContentDefinitionEventHandler.cs | 80 +++++++++++++++++++ .../ContentPartAuditTrailEventProvider.cs | 25 ++++++ .../ContentTypeAuditTrailEventProvider.cs | 23 ++++++ .../GlobalContentDefinitionEditorEvents.cs | 61 ++++++++++++++ .../IContentDefinitionEventHandler.cs | 14 ++++ ...nt-ContentPart-Created.SummaryAdmin.cshtml | 9 +++ ...ContentPart-FieldAdded.SummaryAdmin.cshtml | 12 +++ ...ntentPart-FieldRemoved.SummaryAdmin.cshtml | 10 +++ ...t-FieldSettingsUpdated.SummaryAdmin.cshtml | 10 +++ ...rt-PartSettingsUpdated.SummaryAdmin.cshtml | 9 +++ ...nt-ContentPart-Removed.SummaryAdmin.cshtml | 9 +++ ...nt-ContentType-Created.SummaryAdmin.cshtml | 10 +++ ...-ContentType-PartAdded.SummaryAdmin.cshtml | 10 +++ ...ontentType-PartRemoved.SummaryAdmin.cshtml | 10 +++ ...pe-PartSettingsUpdated.SummaryAdmin.cshtml | 10 +++ ...nt-ContentType-Removed.SummaryAdmin.cshtml | 10 +++ ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 9 +++ 19 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 2817a7e3b..8a2564d11 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -10,4 +10,4 @@ Features: Name: AuditTrail Description: Provides the core audit trail framework. Category: Security - Dependencies: Orchard.Users, Orchard.Roles \ No newline at end of file + Dependencies: Orchard.Users, Orchard.Roles, Orchard.ContentTypes \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index a936c5b63..03330ad3e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -91,6 +91,18 @@ + + + + + + + + + + + + @@ -106,6 +118,11 @@ + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs new file mode 100644 index 000000000..bb79ed7d0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Services; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.AuditTrail.Providers.ContentDefinition { + public class ContentDefinitionEventHandler : IContentDefinitionEventHandler { + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + + public ContentDefinitionEventHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { + _auditTrailManager = auditTrailManager; + _wca = wca; + } + + public void ContentTypeCreated(dynamic context) { + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.Created, context.ContentTypeDefinition); + } + + public void ContentTypeRemoved(dynamic context) { + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.Removed, context.ContentTypeDefinition); + } + + public void ContentPartCreated(dynamic context) { + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.Created, context.ContentPartDefinition); + } + + public void ContentPartRemoved(dynamic context) { + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.Removed, context.ContentPartDefinition); + } + + public void ContentPartAttached(dynamic context) { + RecordContentTypePartAuditTrail(ContentTypeAuditTrailEventProvider.PartAdded, context.ContentTypeName, context.ContentPartName); + } + + public void ContentPartDetached(dynamic context) { + RecordContentTypePartAuditTrail(ContentTypeAuditTrailEventProvider.PartRemoved, context.ContentTypeName, context.ContentPartName); + } + + public void ContentFieldAttached(dynamic context) { + var eventData = new Dictionary { + {"ContentPartName", context.ContentPartName}, + {"ContentFieldName", context.ContentFieldName}, + {"ContentFieldTypeName", context.ContentFieldTypeName}, + {"ContentFieldDisplayName", context.ContentFieldDisplayName} + }; + _auditTrailManager.Record(ContentPartAuditTrailEventProvider.FieldAdded, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); + } + + public void ContentFieldDetached(dynamic context) { + var eventData = new Dictionary { + {"ContentPartName", context.ContentPartName}, + {"ContentFieldName", context.ContentFieldName} + }; + _auditTrailManager.Record(ContentPartAuditTrailEventProvider.FieldRemoved, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); + } + + private void RecordContentTypeAuditTrail(string eventName, ContentTypeDefinition contentTypeDefinition) { + var eventData = new Dictionary { + {"ContentTypeName", contentTypeDefinition.Name}, + {"ContentTypeDisplayName", contentTypeDefinition.DisplayName}, + }; + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeDefinition.Name); + } + + private void RecordContentPartAuditTrail(string eventName, ContentPartDefinition contentPartDefinition) { + var eventData = new Dictionary { + {"ContentPartName", contentPartDefinition.Name} + }; + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartDefinition.Name); + } + + private void RecordContentTypePartAuditTrail(string eventName, string contentTypeName, string contentPartName) { + var eventData = new Dictionary { + {"ContentTypeName", contentTypeName}, + {"ContentPartName", contentPartName} + }; + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs new file mode 100644 index 000000000..6b5427a3a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -0,0 +1,25 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Providers.ContentDefinition { + public class ContentPartAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string Created = "Created"; + public const string Removed = "Removed"; + public const string DescriptionChanged = "DescriptionChanged"; + public const string FieldAdded = "FieldAdded"; + public const string FieldRemoved = "FieldRemoved"; + public const string PartSettingsUpdated = "PartSettingsUpdated"; + public const string FieldSettingsUpdated = "FieldSettingsUpdated"; + + public override void Describe(DescribeContext context) { + context.For("ContentPart", T("Content Part")) + .Event(this, Created, T("Created"), T("Content Type was created."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("Content Type was removed."), enableByDefault: true) + .Event(this, DescriptionChanged, T("Description changed"), T("Content Part description was changed."), enableByDefault: true) + .Event(this, FieldAdded, T("Field added"), T("Content Field was added."), enableByDefault: true) + .Event(this, FieldRemoved, T("Field removed"), T("Content Field was removed."), enableByDefault: true) + .Event(this, PartSettingsUpdated, T("Part settings updated"), T("Content Part settings were updated."), enableByDefault: true) + .Event(this, FieldSettingsUpdated, T("Field settings updated"), T("Content Field settings were updated."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs new file mode 100644 index 000000000..4ef7a0222 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -0,0 +1,23 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; + +namespace Orchard.AuditTrail.Providers.ContentDefinition { + public class ContentTypeAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string Created = "Created"; + public const string Removed = "Removed"; + public const string PartAdded = "PartAdded"; + public const string PartRemoved = "PartRemoved"; + public const string TypeSettingsUpdated = "TypeSettingsUpdated"; + public const string PartSettingsUpdated = "PartSettingsUpdated"; + + public override void Describe(DescribeContext context) { + context.For("ContentType", T("Content Type")) + .Event(this, Created, T("Created"), T("Content Type was created."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("Content Type was removed."), enableByDefault: true) + .Event(this, PartAdded, T("Part added"), T("Content Part was added."), enableByDefault: true) + .Event(this, PartRemoved, T("Part removed"), T("Content Part was removed."), enableByDefault: true) + .Event(this, TypeSettingsUpdated, T("Type Settings updated"), T("Content Type settings were updated."), enableByDefault: true) + .Event(this, PartSettingsUpdated, T("Part Settings updated"), T("Content Part settings were updated."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs new file mode 100644 index 000000000..b04a62333 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Services; +using Orchard.ContentManagement; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Builders; +using Orchard.ContentManagement.ViewModels; + +namespace Orchard.AuditTrail.Providers.ContentDefinition { + public class GlobalContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase { + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + + public GlobalContentDefinitionEditorEvents(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { + _auditTrailManager = auditTrailManager; + _wca = wca; + } + + public override IEnumerable TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) { + var eventData = new Dictionary { + {"ContentTypeName", builder.Name} + }; + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.TypeSettingsUpdated, eventData, builder.Name); + yield break; + } + + public override IEnumerable TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) { + var eventData = new Dictionary { + {"ContentPartName", builder.Name}, + {"ContentTypeName", builder.TypeName} + }; + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.TypeName); + yield break; + } + + public override IEnumerable PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) { + var eventData = new Dictionary { + {"ContentPartName", builder.Name} + }; + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); + yield break; + } + + public override IEnumerable PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) { + var eventData = new Dictionary { + {"ContentFieldName", builder.Name}, + {"ContentFieldType", builder.FieldType}, + {"ContentPartName", builder.PartName} + }; + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName); + yield break; + } + + private void RecordContentTypeAuditTrail(string eventName, IDictionary eventData, string contentTypeName) { + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); + } + + private void RecordContentPartAuditTrail(string eventName, IDictionary eventData, string contentPartName) { + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartName); + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs new file mode 100644 index 000000000..e5f921f7c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs @@ -0,0 +1,14 @@ +using Orchard.Events; + +namespace Orchard.AuditTrail.Providers.ContentDefinition { + public interface IContentDefinitionEventHandler : IEventHandler { + void ContentTypeCreated(dynamic context); + void ContentTypeRemoved(dynamic context); + void ContentPartCreated(dynamic context); + void ContentPartRemoved(dynamic context); + void ContentPartAttached(dynamic context); + void ContentPartDetached(dynamic context); + void ContentFieldAttached(dynamic context); + void ContentFieldDetached(dynamic context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml new file mode 100644 index 000000000..9e6b51388 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Created the {0} content part.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml new file mode 100644 index 000000000..6f61b5602 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml @@ -0,0 +1,12 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); + var contentFieldTypeName = eventData.Get("ContentFieldTypeName"); + var contentDisplayName = eventData.Get("ContentDisplayName"); +} + +
+ @T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml new file mode 100644 index 000000000..a88e8c570 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); +} + +
+ @T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..efff40e3f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); +} + +
+ @T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..6bd2ffc76 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Settings for the {0} content part were updated.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml new file mode 100644 index 000000000..e3b7718a1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Removed the {0} content part.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml new file mode 100644 index 000000000..3a4e0ef90 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); +} + +
+ @T("Created the {0} content type.", contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml new file mode 100644 index 000000000..5532bcf39 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml new file mode 100644 index 000000000..137a210a0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..364d52744 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml new file mode 100644 index 000000000..eb9545a7b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); +} + +
+ @T("Removed the {0} content type.", contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..1f6832afd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); +} + +
+ @T("Settings for the {0} content type were updated.", contentTypeName) +
\ No newline at end of file From 83602896b128a0ccf391a9dd4c6f44ab2fb82af0 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Wed, 28 May 2014 00:39:52 +0200 Subject: [PATCH 019/116] Implementing audit trail site settings. --- .../AuditTrailSiteSettingsPartDriver.cs | 64 +++++++++++++++++++ .../AuditTrailSiteSettingsPartHandler.cs | 62 ++++++++++++++++++ .../Modules/Orchard.AuditTrail/Migrations.cs | 6 ++ .../Models/AuditTrailEventSetting.cs | 6 ++ .../Models/AuditTrailSiteSettingsPart.cs | 27 ++++++++ .../Orchard.AuditTrail.csproj | 8 +++ .../Modules/Orchard.AuditTrail/Placement.info | 5 +- .../Orchard.AuditTrail/Styles/admin.css | 11 +++- .../AuditTrailCategorySettingsViewModel.cs | 10 +++ .../AuditTrailEventSettingsViewModel.cs | 11 ++++ .../AuditTrailSiteSettingsViewModel.cs | 10 +++ .../Parts.AuditTrailSiteSettings.cshtml | 56 ++++++++++++++++ 12 files changed, 271 insertions(+), 5 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventSetting.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs new file mode 100644 index 000000000..31679b3d9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs @@ -0,0 +1,64 @@ +using System.Linq; +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.ViewModels; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; + +namespace Orchard.AuditTrail.Drivers { + public class AuditTrailSiteSettingsPartDriver : ContentPartDriver { + private readonly IAuditTrailManager _auditTrailManager; + + public AuditTrailSiteSettingsPartDriver(IAuditTrailManager auditTrailManager) { + _auditTrailManager = auditTrailManager; + } + + protected override DriverResult Editor(AuditTrailSiteSettingsPart part, dynamic shapeHelper) { + return Editor(part, null, shapeHelper); + } + + protected override DriverResult Editor(AuditTrailSiteSettingsPart part, IUpdateModel updater, dynamic shapeHelper) { + return ContentShape("Parts_AuditTrailSiteSettings_Edit", () => { + var descriptors = _auditTrailManager.Describe(); + var eventSettings = part.EventSettings.ToList(); + var viewModel = new AuditTrailSiteSettingsViewModel { + AutoTrim = part.AutoTrim, + AutoTrimThreshold = part.AutoTrimThreshold, + Categories = (from categoryDescriptor in descriptors + select new AuditTrailCategorySettingsViewModel { + Category = categoryDescriptor.Category, + Name = categoryDescriptor.Name, + Events = (from eventDescriptor in categoryDescriptor.Events + let eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventDescriptor.Event) + select new AuditTrailEventSettingsViewModel { + Event = eventDescriptor.Event, + Name = eventDescriptor.Name, + Description = eventDescriptor.Description, + IsEnabled = eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault + }).ToList() + }).ToList() + }; + + if (updater != null) { + if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { + foreach (var eventSettingViewModel in viewModel.Categories.SelectMany(x => x.Events)) { + var eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventSettingViewModel.Event); + + if (eventSetting == null) { + eventSetting = new AuditTrailEventSetting { EventName = eventSettingViewModel.Event}; + eventSettings.Add(eventSetting); + } + + eventSetting.IsEnabled = eventSettingViewModel.IsEnabled; + } + part.EventSettings = eventSettings; + part.AutoTrim = viewModel.AutoTrim; + part.AutoTrimThreshold = viewModel.AutoTrimThreshold; + } + } + + return shapeHelper.EditorTemplate(TemplateName: "Parts.AuditTrailSiteSettings", Model: viewModel, Prefix: Prefix); + }).OnGroup("Audit Trail"); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs new file mode 100644 index 000000000..8f0fc99ba --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Handlers; +using Orchard.Localization; +using Orchard.Logging; + +namespace Orchard.AuditTrail.Handlers { + public class AuditTrailSiteSettingsPartHandler : ContentHandler { + public AuditTrailSiteSettingsPartHandler() { + OnActivated(SetupLazyFields); + OnGetContentItemMetadata(GetMetadata); + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + + private void GetMetadata(GetContentItemMetadataContext context, AuditTrailSiteSettingsPart part) { + context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Audit Trail"))); + } + + private void SetupLazyFields(ActivatedContentContext context, AuditTrailSiteSettingsPart part) { + part._eventProviderSettingsField.Loader(() => DeserializeProviderConfiguration(part.Retrieve("Events"))); + part._eventProviderSettingsField.Setter(value => { + part.Store("Events", SerializeProviderConfiguration(value)); + return value; + }); + } + + private IEnumerable DeserializeProviderConfiguration(string data) { + if (String.IsNullOrWhiteSpace(data)) + return Enumerable.Empty(); + + try { + var doc = XDocument.Parse(data); + return doc.Element("Events").Elements("Event").Select(x => new AuditTrailEventSetting { + EventName = x.Attr("Name"), + IsEnabled = x.Attr("IsEnabled") + }).ToArray(); + + } + catch (Exception ex) { + Logger.Error(ex, "Error occurred during deserialization of audit trail settings."); + } + return Enumerable.Empty(); + } + + private string SerializeProviderConfiguration(IEnumerable settings) { + var doc = new XDocument( + new XElement("Events", + settings.Select(x => + new XElement("Event", + new XAttribute("Name", x.EventName), + new XAttribute("IsEnabled", x.IsEnabled))))); + + return doc.ToString(SaveOptions.DisableFormatting); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs index f399c1756..8da58b6cd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -22,6 +22,12 @@ namespace Orchard.AuditTrail { .Attachable() .WithDescription("Enables the user to enter a comment about the change when saving a content item.")); + ContentDefinitionManager.AlterPartDefinition("AuditTrailSiteSettingsPart", part => part + .Attachable(false) + .WithDescription("Stores the audit trail settings.")); + + ContentDefinitionManager.AlterTypeDefinition("Site", type => type.WithPart("AuditTrailSiteSettingsPart")); + return 1; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventSetting.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventSetting.cs new file mode 100644 index 000000000..eb7b82ced --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventSetting.cs @@ -0,0 +1,6 @@ +namespace Orchard.AuditTrail.Models { + public class AuditTrailEventSetting { + public string EventName { get; set; } + public bool IsEnabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs new file mode 100644 index 000000000..e982f7562 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.Core.Common.Utilities; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailSiteSettingsPart : ContentPart { + internal LazyField> _eventProviderSettingsField = new LazyField>(); + + public bool AutoTrim { + get { return this.Retrieve(x => x.AutoTrim, defaultValue: false); } + set { this.Store(x => x.AutoTrim, value); } + } + + /// + /// Threshold in days. + /// + public int AutoTrimThreshold { + get { return this.Retrieve(x => x.AutoTrimThreshold, defaultValue: 10); } + set { this.Store(x => x.AutoTrimThreshold, value); } + } + + public IEnumerable EventSettings { + get { return _eventProviderSettingsField.Value; } + set { _eventProviderSettingsField.Value = value; } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 03330ad3e..e0f8ab083 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -103,6 +103,7 @@ +
@@ -117,7 +118,14 @@ + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info index 5f9a1ba88..baff8c89c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -1,8 +1,9 @@  - + Parts_AuditTrail="Content:after.3" + Parts_AuditTrailSiteSettings_Edit="Content:0"/> + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css index b3eb28f2a..1cf09adea 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -10,9 +10,14 @@ font-size: 0.8em; } -.audit-trail-list .audit-trail-record .event-details { -} - .audit-trail-record-details fieldset legend span { font-size: 0.8em; +} + +.audit-trail-site-settings table th.event-name { + width: 250px; +} + +.audit-trail-site-settings table th.event-enabled { + width: 60px; } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs new file mode 100644 index 000000000..04d619a08 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Orchard.Localization; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailCategorySettingsViewModel { + public string Category { get; set; } + public LocalizedString Name { get; set; } + public IList Events { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs new file mode 100644 index 000000000..ce652ced7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs @@ -0,0 +1,11 @@ +using System.Collections; +using Orchard.Localization; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailEventSettingsViewModel { + public string Event { get; set; } + public LocalizedString Name { get; set; } + public LocalizedString Description { get; set; } + public bool IsEnabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs new file mode 100644 index 000000000..6a2ba0aa9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs @@ -0,0 +1,10 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailSiteSettingsViewModel { + public bool AutoTrim { get; set; } + public int AutoTrimThreshold { get; set; } + public IList Categories { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml new file mode 100644 index 000000000..9100d388b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml @@ -0,0 +1,56 @@ +@model Orchard.AuditTrail.ViewModels.AuditTrailSiteSettingsViewModel +@{ + Style.Include("admin.css"); +} +
+
+ @T("Auto Trim Settings") +
+ @Html.CheckBoxFor(m => m.AutoTrim) + @Html.LabelFor(m => m.AutoTrim, T("Automatically trim the audit trail for this site").Text, new { @class = "forcheckbox" }) + @T("Check this option to automatically trim the audit trail.") +
+
+ @Html.LabelFor(m => m.AutoTrimThreshold, T("Auto-trim threshold")) + @Html.TextBoxFor(m => m.AutoTrimThreshold, new { @class = "text small" }) + @T("Specify the number of days of audit log data to retain.") +
+
+
+ @T("Specify the events to audit") + @{ + var i = 0; + } + @foreach (var category in Model.Categories) { +
+ @category.Name + + + + + + + + + + @{ var j = 0; } + @foreach (var evnt in category.Events) { + var checkboxId = String.Format("Event{0}{1}", i, j); + + + + + + j++; + } +
@T("Event")@T("Description")@T("Enabled")
+ + @evnt.Name + @evnt.Description + checked="checked"} /> +
+
+ i++; + } +
+
\ No newline at end of file From 16a67320cc2ca0091b4de98b8b990907fcd4de42 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Wed, 28 May 2014 11:57:56 +0200 Subject: [PATCH 020/116] Updating audit trail manager to take event settings into account. --- .../AuditTrailSiteSettingsPartHandler.cs | 7 +++- .../Models/AuditTrailEventRecordResult.cs | 6 +++ .../Orchard.AuditTrail.csproj | 1 + .../Services/AuditTrailManager.cs | 38 +++++++++++++++++-- .../Services/IAuditTrailManager.cs | 4 +- 5 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecordResult.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs index 8f0fc99ba..4a41b300e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Orchard.AuditTrail.Models; +using Orchard.Caching; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.Localization; @@ -10,7 +11,10 @@ using Orchard.Logging; namespace Orchard.AuditTrail.Handlers { public class AuditTrailSiteSettingsPartHandler : ContentHandler { - public AuditTrailSiteSettingsPartHandler() { + private readonly ISignals _signals; + + public AuditTrailSiteSettingsPartHandler(ISignals signals) { + _signals = signals; OnActivated(SetupLazyFields); OnGetContentItemMetadata(GetMetadata); T = NullLocalizer.Instance; @@ -26,6 +30,7 @@ namespace Orchard.AuditTrail.Handlers { part._eventProviderSettingsField.Loader(() => DeserializeProviderConfiguration(part.Retrieve("Events"))); part._eventProviderSettingsField.Setter(value => { part.Store("Events", SerializeProviderConfiguration(value)); + _signals.Trigger("AuditTrail.EventSettings"); return value; }); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecordResult.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecordResult.cs new file mode 100644 index 000000000..4480a7471 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecordResult.cs @@ -0,0 +1,6 @@ +namespace Orchard.AuditTrail.Models { + public class AuditTrailEventRecordResult { + public AuditTrailEventRecord Record { get; set; } + public bool IsDisabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index e0f8ab083..3d2b81e19 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -119,6 +119,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 54db35ab5..be8020858 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.Linq; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; +using Orchard.Caching; using Orchard.Collections; +using Orchard.ContentManagement; using Orchard.Data; using Orchard.Security; using Orchard.Services; +using Orchard.Settings; namespace Orchard.AuditTrail.Services { public class AuditTrailManager : Component, IAuditTrailManager { @@ -15,19 +18,28 @@ namespace Orchard.AuditTrail.Services { private readonly IClock _clock; private readonly IAuditTrailEventHandler _auditTrailEventHandlers; private readonly IEventDataSerializer _serializer; + private readonly ICacheManager _cacheManager; + private readonly ISiteService _siteService; + private readonly ISignals _signals; public AuditTrailManager( IRepository auditTrailRepository, IAuditTrailEventProvider providers, IClock clock, IAuditTrailEventHandler auditTrailEventHandlers, - IEventDataSerializer serializer) { + IEventDataSerializer serializer, + ICacheManager cacheManager, + ISiteService siteService, + ISignals signals) { _auditTrailRepository = auditTrailRepository; _providers = providers; _clock = clock; _auditTrailEventHandlers = auditTrailEventHandlers; _serializer = serializer; + _cacheManager = cacheManager; + _siteService = siteService; + _signals = signals; } public IPageOfItems GetRecords(int page, int pageSize, AuditTrailFilterParameters filter = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending) { @@ -66,7 +78,14 @@ namespace Orchard.AuditTrail.Services { return _auditTrailRepository.Get(id); } - public AuditTrailEventRecord Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { + public AuditTrailEventRecordResult Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { + var eventDescriptor = Describe(eventName); + if(!IsEnabled(eventDescriptor)) + return new AuditTrailEventRecordResult { + Record = null, + IsDisabled = true + }; + if (properties == null) properties = new Dictionary(); if (eventData == null) eventData = new Dictionary(); @@ -80,7 +99,6 @@ namespace Orchard.AuditTrail.Services { }; _auditTrailEventHandlers.Create(context); - var eventDescriptor = Describe(eventName); var record = new AuditTrailEventRecord { Category = eventDescriptor.CategoryDescriptor.Category, @@ -94,7 +112,19 @@ namespace Orchard.AuditTrail.Services { }; _auditTrailRepository.Create(record); - return record; + return new AuditTrailEventRecordResult { + Record = record, + IsDisabled = false + }; + } + + private bool IsEnabled(AuditTrailEventDescriptor eventDescriptor) { + var settingsDictionary = _cacheManager.Get("AuditTrail.EventSettings", context => { + context.Monitor(_signals.When("AuditTrail.EventSettings")); + return _siteService.GetSiteSettings().As().EventSettings.ToDictionary(x => x.EventName); + }); + var setting = settingsDictionary.ContainsKey(eventDescriptor.Event) ? settingsDictionary[eventDescriptor.Event] : default(AuditTrailEventSetting); + return setting != null ? setting.IsEnabled : eventDescriptor.IsEnabledByDefault; } public IEnumerable Describe() { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 9b9d25ea3..3039c0be7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -33,8 +33,8 @@ namespace Orchard.AuditTrail.Services { /// A property bag of custom event data that will be stored with the event record. /// The name of a custom key to use when filtering events. /// The value of a custom filter key to filter on. - /// Returns the created audit trail event record. - AuditTrailEventRecord Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; + /// Returns the created audit trail event record if the specified event was not disabled. + AuditTrailEventRecordResult Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; /// /// Describes all audit trail events provided by the system. From f3c78a1785758b29cfdc137650a20056cf90811f Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Wed, 28 May 2014 12:15:28 +0200 Subject: [PATCH 021/116] Updating and implementing permissions. --- .../Modules/Orchard.AuditTrail/AdminMenu.cs | 2 +- .../Controllers/AdminController.cs | 4 +- .../Drivers/AuditTrailPartDriver.cs | 53 ++++++++++--------- .../AuditTrailSiteSettingsPartDriver.cs | 8 ++- .../Modules/Orchard.AuditTrail/Permissions.cs | 8 +-- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs index 84a8843d1..81f4192bc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs @@ -9,7 +9,7 @@ namespace Orchard.AuditTrail { builder.AddImageSet("audit-trail") .Add(T("Audit Trail"), "12", menuItem => menuItem .Action("Index", "Admin", new { area = "Orchard.AuditTrail" }) - .Permission(Permissions.ManageAuditTrail)); + .Permission(Permissions.ManageAuditTrailSettings)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 02353d50f..3cc4e8215 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -28,7 +28,7 @@ namespace Orchard.AuditTrail.Controllers { public dynamic New { get; private set; } public ActionResult Index(PagerParameters pagerParameters, AuditTrailFilterViewModel filterParameters) { - if(!_authorizer.Authorize(Permissions.ManageAuditTrail)) + if(!_authorizer.Authorize(Permissions.ViewAuditTrail)) return new HttpUnauthorizedResult(); var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters); @@ -64,7 +64,7 @@ namespace Orchard.AuditTrail.Controllers { } public ActionResult Detail(int id) { - if (!_authorizer.Authorize(Permissions.ManageAuditTrail)) + if (!_authorizer.Authorize(Permissions.ViewAuditTrail)) return new HttpUnauthorizedResult(); var record = _auditTrailManager.GetRecord(id); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 7c1cfb1e8..206e6bcdd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -37,33 +37,34 @@ namespace Orchard.AuditTrail.Drivers { return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail.Comment", Prefix: Prefix); })); } + if (_services.Authorizer.Authorize(Permissions.ViewAuditTrail)) { + if (settings.ShowAuditTrailLink) { + results.Add(ContentShape("Parts_AuditTrail_Link", () => shapeHelper.Parts_AuditTrail_Link())); + } - if (settings.ShowAuditTrailLink) { - results.Add(ContentShape("Parts_AuditTrail_Link", () => shapeHelper.Parts_AuditTrail_Link())); - } - - if (settings.ShowAuditTrail) { - results.Add(ContentShape("Parts_AuditTrail", () => { - var pager = new Pager(_services.WorkContext.CurrentSite, null, null); - var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { - FilterKey = "content", - FilterValue = part.Id.ToString(CultureInfo.InvariantCulture) - }); - var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var eventDescriptors = from c in _auditTrailManager.Describe() - from e in c.Events - select e; - var recordViewModels = from record in pageOfData - let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) - where descriptor != null - select new AuditTrailEventSummaryViewModel { - Record = record, - EventDescriptor = descriptor, - CategoryDescriptor = descriptor.CategoryDescriptor, - SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") - }; - return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape); - })); + if (settings.ShowAuditTrail) { + results.Add(ContentShape("Parts_AuditTrail", () => { + var pager = new Pager(_services.WorkContext.CurrentSite, null, null); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { + FilterKey = "content", + FilterValue = part.Id.ToString(CultureInfo.InvariantCulture) + }); + var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); + var eventDescriptors = from c in _auditTrailManager.Describe() + from e in c.Events + select e; + var recordViewModels = from record in pageOfData + let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) + where descriptor != null + select new AuditTrailEventSummaryViewModel { + Record = record, + EventDescriptor = descriptor, + CategoryDescriptor = descriptor.CategoryDescriptor, + SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") + }; + return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape); + })); + } } return Combined(results.ToArray()); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs index 31679b3d9..9e536b4e6 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs @@ -4,13 +4,16 @@ using Orchard.AuditTrail.Services; using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; +using Orchard.Security; namespace Orchard.AuditTrail.Drivers { public class AuditTrailSiteSettingsPartDriver : ContentPartDriver { private readonly IAuditTrailManager _auditTrailManager; + private readonly IAuthorizer _authorizer; - public AuditTrailSiteSettingsPartDriver(IAuditTrailManager auditTrailManager) { + public AuditTrailSiteSettingsPartDriver(IAuditTrailManager auditTrailManager, IAuthorizer authorizer) { _auditTrailManager = auditTrailManager; + _authorizer = authorizer; } protected override DriverResult Editor(AuditTrailSiteSettingsPart part, dynamic shapeHelper) { @@ -18,6 +21,9 @@ namespace Orchard.AuditTrail.Drivers { } protected override DriverResult Editor(AuditTrailSiteSettingsPart part, IUpdateModel updater, dynamic shapeHelper) { + if (!_authorizer.Authorize(Permissions.ManageAuditTrailSettings)) + return null; + return ContentShape("Parts_AuditTrailSiteSettings_Edit", () => { var descriptors = _auditTrailManager.Describe(); var eventSettings = part.EventSettings.ToList(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs index dbf8ad8d1..2fd175e1e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs @@ -4,19 +4,21 @@ using Orchard.Security.Permissions; namespace Orchard.AuditTrail { public class Permissions : IPermissionProvider { - public static readonly Permission ManageAuditTrail = new Permission { Description = "Manage Audit Trail", Name = "ManageAuditTrail" }; + public static readonly Permission ViewAuditTrail = new Permission { Description = "View Audit Trail", Name = "ViewAuditTrail" }; + public static readonly Permission ManageAuditTrailSettings = new Permission { Description = "Manage audit trail settings", Name = "ManageAuditTrailSettings" }; public virtual Feature Feature { get; set; } public IEnumerable GetPermissions() { - yield return ManageAuditTrail; + yield return ViewAuditTrail; + yield return ManageAuditTrailSettings; } public IEnumerable GetDefaultStereotypes() { return new[] { new PermissionStereotype { Name = "Administrator", - Permissions = new[] {ManageAuditTrail} + Permissions = new[] {ViewAuditTrail, ManageAuditTrailSettings} } }; } From 45beff3fe014cd8dd2f357f42e5f388429cbf1e9 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 1 Jun 2014 14:53:50 +0200 Subject: [PATCH 022/116] Incremental work on event details view. --- .../Controllers/AdminController.cs | 7 ++-- .../Orchard.AuditTrail.csproj | 20 ++++++++++- .../Content/ContentAuditTrailEventShapes.cs | 33 +++++++++++++++++++ .../Providers/Content/GlobalContentHandler.cs | 19 +++++++++-- .../Services/AuditTrailEventDisplayBuilder.cs | 2 +- .../Orchard.AuditTrail/Styles/admin.css | 2 +- .../ViewModels/AuditTrailDetailsViewModel.cs | 6 +++- .../Views/Admin/Detail.cshtml | 19 +++++++++-- .../Views/AuditTrailEvent-Content.cshtml | 33 ++++++++----------- ...AuditTrailEvent-ContentPart-Created.cshtml | 9 +++++ ...itTrailEvent-ContentPart-FieldAdded.cshtml | 12 +++++++ ...TrailEvent-ContentPart-FieldRemoved.cshtml | 10 ++++++ ...nt-ContentPart-FieldSettingsUpdated.cshtml | 10 ++++++ ...ent-ContentPart-PartSettingsUpdated.cshtml | 9 +++++ ...AuditTrailEvent-ContentPart-Removed.cshtml | 9 +++++ ...AuditTrailEvent-ContentType-Created.cshtml | 10 ++++++ ...ditTrailEvent-ContentType-PartAdded.cshtml | 10 ++++++ ...tTrailEvent-ContentType-PartRemoved.cshtml | 10 ++++++ ...ent-ContentType-PartSettingsUpdated.cshtml | 10 ++++++ ...AuditTrailEvent-ContentType-Removed.cshtml | 10 ++++++ ...ent-ContentType-TypeSettingsUpdated.cshtml | 9 +++++ ...uditTrailEvent-Role-PermissionAdded.cshtml | 10 ++++++ ...itTrailEvent-Role-PermissionRemoved.cshtml | 10 ++++++ .../AuditTrailEvent-Role-RoleCreated.cshtml | 9 +++++ .../AuditTrailEvent-Role-RoleRenamed.cshtml | 10 ++++++ .../Views/AuditTrailEvent-User.cshtml | 9 +++++ .../Views/AuditTrailEvent.cshtml | 18 ++-------- 27 files changed, 280 insertions(+), 45 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 3cc4e8215..95c9496a7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -68,9 +68,12 @@ namespace Orchard.AuditTrail.Controllers { return new HttpUnauthorizedResult(); var record = _auditTrailManager.GetRecord(id); - var recordShape = _displayBuilder.BuildDisplay(record, "Detail"); + var descriptor = _auditTrailManager.Describe(record.Event); + var detailsShape = _displayBuilder.BuildDisplay(record, "Detail"); var viewModel = new AuditTrailDetailsViewModel { - Record = recordShape + Record = record, + Descriptor = descriptor, + DetailsShape = detailsShape }; return View(viewModel); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 3d2b81e19..5f2e41f16 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -101,9 +101,26 @@ - + + + + + + + + + + + + + + + + + + @@ -120,6 +137,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs new file mode 100644 index 000000000..9b6fe391f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.DisplayManagement.Descriptors; +using Orchard.Environment; + +namespace Orchard.AuditTrail.Providers.Content { + public class ContentAuditTrailEventShapes : IShapeTableProvider { + private readonly Work _contentManager; + public ContentAuditTrailEventShapes(Work contentManager) { + _contentManager = contentManager; + } + + public void Discover(ShapeTableBuilder builder) { + builder.Describe("AuditTrailEvent").OnDisplaying(context => { + var record = (AuditTrailEventRecord)context.Shape.Record; + + if (record.Category != "Content" || context.ShapeMetadata.DisplayType != "Detail") + return; + + var eventData = (IDictionary)context.Shape.EventData; + var contentItemId = eventData.Get("ContentItemId"); + var previousContentItemVersionId = eventData.Get("PreviousContentItemVersionId"); + var contentItem = _contentManager.Value.Get(contentItemId); + var previousVersion = previousContentItemVersionId > 0 ? _contentManager.Value.Get(contentItemId, VersionOptions.VersionRecord(previousContentItemVersionId)) : default(ContentItem); + + context.Shape.ContentItem = contentItem; + context.Shape.PreviousVersion = previousVersion; + }); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index df653fb98..82e50b806 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -22,12 +22,14 @@ namespace Orchard.AuditTrail.Providers.Content { } protected override void Updated(UpdateContentContext context) { - // TODO: Update ContentManager to expose the previous version of the updated content item. - RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem, context.ContentItem.VersionRecord); + var currentVersion = context.UpdatingItemVersionRecord; + var previousVersion = GetPreviousVersion(currentVersion); + RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem, previousVersion); } protected override void Published(PublishContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Published, context.ContentItem); + var previousVersion = context.PreviousItemVersionRecord; + RecordAuditTrail(ContentAuditTrailEventProvider.Published, context.ContentItem, previousVersion); } protected override void Unpublished(PublishContentContext context) { @@ -38,6 +40,17 @@ namespace Orchard.AuditTrail.Providers.Content { RecordAuditTrail(ContentAuditTrailEventProvider.Removed, context.ContentItem); } + private ContentItemVersionRecord GetPreviousVersion(ContentItemVersionRecord currentVersion) { + var number = currentVersion.Number; + var previousVersion = default(ContentItemVersionRecord); + + while (previousVersion == null) { + var contentItem = _contentManager.Get(currentVersion.ContentItemRecord.Id, VersionOptions.Number(--number)); + previousVersion = contentItem != null ? contentItem.VersionRecord : default(ContentItemVersionRecord); + } + return previousVersion; + } + private void RecordAuditTrail(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { var title = _contentManager.GetItemMetadata(content).DisplayText; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs index fa06f7752..ae889fc4a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -25,7 +25,7 @@ namespace Orchard.AuditTrail.Services { metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", record.Category, GetShortName(record.Event))); + metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}__{1}", record.Category, GetShortName(record.Event))); metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, GetShortName(record.Event))); return auditTrailEventShape; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css index 1cf09adea..5a5d66a72 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -10,7 +10,7 @@ font-size: 0.8em; } -.audit-trail-record-details fieldset legend span { +.audit-trail-event fieldset legend span { font-size: 0.8em; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs index bfe8ecb07..a794234cb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs @@ -1,5 +1,9 @@ +using Orchard.AuditTrail.Models; + namespace Orchard.AuditTrail.ViewModels { public class AuditTrailDetailsViewModel { - public dynamic Record { get; set; } + public AuditTrailEventRecord Record { get; set; } + public AuditTrailEventDescriptor Descriptor { get; set; } + public dynamic DetailsShape { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml index 4cf8473f7..e3d76fbc1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml @@ -2,6 +2,21 @@ @{ Style.Include("admin.css"); } -
- @Display(Model.Record) +@{ + var record = Model.Record; + var descriptor = Model.Descriptor; +} +
+
+ @descriptor.Name - @descriptor.CategoryDescriptor.Name +
+ @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @if (!String.IsNullOrWhiteSpace(record.UserName)) { + @T(" | ")@record.UserName + } +
+
+
+
+ @Display(Model.DetailsShape)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 7d51518ab..ccea5eb2c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -1,21 +1,16 @@ -@using Orchard.AuditTrail.Helpers -@using Orchard.AuditTrail.Models +@using Orchard.ContentManagement @{ - var record = (AuditTrailEventRecord)Model.Record; - var descriptor = (AuditTrailEventDescriptor) Model.Descriptor; - var eventData = (IDictionary)Model.EventData; - var title = eventData.Get("Title"); - var contentItemId = eventData.Get("ContentItemId"); - var contentItemVersionNumber = eventData.Get("ContentItemVersionNumber"); + var contentItem = (ContentItem) Model.ContentItem; + var previousVersion = (ContentItem) Model.PreviousVersion; } -
-
- @descriptor.Name - @descriptor.CategoryDescriptor.Name -
- @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) - @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@record.UserName - } -
-
-
\ No newline at end of file + +
+ @T("This version:") + @Html.ItemEditLink(contentItem) +
+@if (previousVersion != null) { +
+ @T("Previous version:") + @Html.ItemEditLink(previousVersion) +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml new file mode 100644 index 000000000..9e6b51388 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Created the {0} content part.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml new file mode 100644 index 000000000..6f61b5602 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml @@ -0,0 +1,12 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); + var contentFieldTypeName = eventData.Get("ContentFieldTypeName"); + var contentDisplayName = eventData.Get("ContentDisplayName"); +} + +
+ @T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml new file mode 100644 index 000000000..a88e8c570 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); +} + +
+ @T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml new file mode 100644 index 000000000..efff40e3f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); +} + +
+ @T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml new file mode 100644 index 000000000..6bd2ffc76 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Settings for the {0} content part were updated.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml new file mode 100644 index 000000000..e3b7718a1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Removed the {0} content part.", contentPartName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml new file mode 100644 index 000000000..3a4e0ef90 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); +} + +
+ @T("Created the {0} content type.", contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml new file mode 100644 index 000000000..5532bcf39 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml new file mode 100644 index 000000000..137a210a0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml new file mode 100644 index 000000000..364d52744 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); +} + +
+ @T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml new file mode 100644 index 000000000..eb9545a7b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); +} + +
+ @T("Removed the {0} content type.", contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml new file mode 100644 index 000000000..1f6832afd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); +} + +
+ @T("Settings for the {0} content type were updated.", contentTypeName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml new file mode 100644 index 000000000..764446ae2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); + var permissionName = eventData.Get("PermissionName"); +} + +
+ @T("Added the {0} permission to the {1} role.", permissionName, roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml new file mode 100644 index 000000000..870bf00f5 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); + var permissionName = eventData.Get("PermissionName"); +} + +
+ @T("Removed the {0} permission from the {1} role.", permissionName, roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml new file mode 100644 index 000000000..91d579147 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); +} + +
+ @T("Created {0} role.", roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml new file mode 100644 index 000000000..8611bd024 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var previousRoleName = eventData.Get("PreviousRoleName"); + var newRoleName = eventData.Get("NewRoleName"); +} + +
+ @T("Renamed {0} to {1}.", previousRoleName, newRoleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml new file mode 100644 index 000000000..9a09f35fd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var userName = eventData.Get("UserName"); +} + +
+ @userName +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml index 83605f367..ff029a741 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml @@ -1,15 +1,3 @@ -@using Orchard.AuditTrail.Models -@{ - var record = (AuditTrailEventRecord)Model.Record; -} -
-
- @record.Event - @record.Category -
- @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) - @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@record.UserName - } -
-
-
\ No newline at end of file +@{ + var model = Model; +} \ No newline at end of file From 11472a96e4778caeb6731968975d98ab14098eb0 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Sun, 1 Jun 2014 15:25:23 +0200 Subject: [PATCH 023/116] Implementing Import/Export. --- .../ImportExport/AuditTrailExportHandler.cs | 62 +++++++++++++++++++ .../ImportExport/AuditTrailExportStep.cs | 14 +++++ .../ImportExport/AuditTrailImportHandler.cs | 39 ++++++++++++ .../Orchard.AuditTrail.csproj | 3 + 4 files changed, 118 insertions(+) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs new file mode 100644 index 000000000..763b6e31e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Orchard.AuditTrail.Models; +using Orchard.Data; +using Orchard.Events; + +namespace Orchard.AuditTrail.ImportExport { + public interface IExportEventHandler : IEventHandler { + void Exporting(dynamic context); + void Exported(dynamic context); + } + + public class AuditTrailExportEventHandler : IExportEventHandler { + private readonly IRepository _auditTrailEventRepository; + + public AuditTrailExportEventHandler(IRepository auditTrailEventRepository) { + _auditTrailEventRepository = auditTrailEventRepository; + } + + public void Exporting(dynamic context) { + } + + public void Exported(dynamic context) { + + if (!((IEnumerable)context.ExportOptions.CustomSteps).Contains("AuditTrail")) { + return; + } + + var records = _auditTrailEventRepository.Table.ToList(); + + if (!records.Any()) { + return; + } + + var root = new XElement("AuditTrail"); + context.Document.Element("Orchard").Add(root); + + foreach (var record in records) { + root.Add(new XElement("Event", + new XAttribute("Name", record.Event), + new XAttribute("Category", record.Category), + new XAttribute("User", record.UserName), + new XAttribute("CreatedUtc", record.CreatedUtc), + new XAttribute("EventFilterKey", record.EventFilterKey), + new XAttribute("EventFilterData", record.EventFilterData), + CreateElement("Comment", record.Comment), + CreateCDataElement("EventData", record.EventData))); + } + } + + private static XElement CreateElement(string name, string value) { + return !String.IsNullOrWhiteSpace(value) ? new XElement(name, value) : null; + } + + private static XElement CreateCDataElement(string name, string value) { + return !String.IsNullOrWhiteSpace(value) ? new XElement(name, new XCData(value)) : null; + } + } +} + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs new file mode 100644 index 000000000..8caba42c4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Orchard.Events; + +namespace Orchard.AuditTrail.ImportExport { + public interface ICustomExportStep : IEventHandler { + void Register(IList steps); + } + + public class AuditTrailExportStep : ICustomExportStep { + public void Register(IList steps) { + steps.Add("AuditTrail"); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs new file mode 100644 index 000000000..84dc8e8d7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs @@ -0,0 +1,39 @@ +using System; +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.Data; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.AuditTrail.ImportExport { + public class AuditTrailImportHandler : Component, IRecipeHandler { + private readonly IRepository _auditTrailEventRepository; + + public AuditTrailImportHandler(IRepository auditTrailEventRepository) { + _auditTrailEventRepository = auditTrailEventRepository; + } + + public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "AuditTrail", StringComparison.OrdinalIgnoreCase)) { + return; + } + + foreach (var eventElement in recipeContext.RecipeStep.Step.Elements()) { + var record = new AuditTrailEventRecord { + Event = eventElement.Attr("Name"), + Category = eventElement.Attr("Category"), + UserName = eventElement.Attr("User"), + CreatedUtc = eventElement.Attr("CreatedUtc"), + EventFilterKey = eventElement.Attr("EventFilterKey"), + EventFilterData = eventElement.Attr("EventFilterData"), + Comment = eventElement.El("Comment"), + EventData = eventElement.El("EventData"), + }; + + _auditTrailEventRepository.Create(record); + } + + recipeContext.Executed = true; + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 5f2e41f16..235f13d75 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -136,6 +136,9 @@ + + + From 5b73e80703a06f6674fccdc7739f4b211cfa4346 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 15:12:56 +0200 Subject: [PATCH 024/116] Incremental work on diffgram. --- .../Orchard.AuditTrail.csproj | 9 ++ .../Content/ContentAuditTrailEventShapes.cs | 14 ++- .../Providers/Content/DiffGramAnalyzer.cs | 98 +++++++++++++++++++ .../Providers/Content/DiffNode.cs | 8 ++ .../Providers/Content/DiffType.cs | 6 ++ .../Providers/Content/IDiffGramAnalyzer.cs | 9 ++ 6 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffType.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 235f13d75..0bc6645e7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -69,9 +69,14 @@ + + False + Lib\XmlDiffPatch\xmldiffpatch.dll + + @@ -141,6 +146,10 @@ + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs index 9b6fe391f..a301a1ae5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; using Orchard.ContentManagement; @@ -8,8 +9,11 @@ using Orchard.Environment; namespace Orchard.AuditTrail.Providers.Content { public class ContentAuditTrailEventShapes : IShapeTableProvider { private readonly Work _contentManager; - public ContentAuditTrailEventShapes(Work contentManager) { + private readonly IDiffGramAnalyzer _analyzer; + + public ContentAuditTrailEventShapes(Work contentManager, IDiffGramAnalyzer analyzer) { _contentManager = contentManager; + _analyzer = analyzer; } public void Discover(ShapeTableBuilder builder) { @@ -25,6 +29,14 @@ namespace Orchard.AuditTrail.Providers.Content { var contentItem = _contentManager.Value.Get(contentItemId); var previousVersion = previousContentItemVersionId > 0 ? _contentManager.Value.Get(contentItemId, VersionOptions.VersionRecord(previousContentItemVersionId)) : default(ContentItem); + if (previousVersion != null) { + var previousVersionXml = _contentManager.Value.Export(previousVersion); + var currentVersionXml = _contentManager.Value.Export(contentItem); + var diffGram = _analyzer.GenerateDiffGram(previousVersionXml, currentVersionXml); + var diffNodes = _analyzer.Analyze(previousVersionXml, diffGram).ToArray(); + context.Shape.DiffNodes = diffNodes; + } + context.Shape.ContentItem = contentItem; context.Shape.PreviousVersion = previousVersion; }); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs new file mode 100644 index 000000000..d1029b10c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using System.Xml.Linq; +using Microsoft.XmlDiffPatch; + +namespace Orchard.AuditTrail.Providers.Content { + public class DiffGramAnalyzer : IDiffGramAnalyzer { + public XElement GenerateDiffGram(XElement element1, XElement element2) { + using(var node1Reader = element1.CreateReader()) + using (var node2Reader = element2.CreateReader()) { + var result = new XDocument(); + using (var writer = result.CreateWriter()) { + var diff = + new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreWhitespace | + XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreXmlDecl); + diff.Compare(node1Reader, node2Reader, writer); + writer.Flush(); + writer.Close(); + } + + return result.Root; + } + } + + public IEnumerable Analyze(XElement original, XElement diffGram) { + var stack = new Stack(); + + stack.Push(new XElement("original", original)); + + using (var reader = diffGram.CreateReader()) { + while (!reader.EOF) { + var doRead = true; + if (reader.LocalName == "xmldiff") + reader.Read(); + switch (reader.NodeType) { + case XmlNodeType.Element: + var match = reader.GetAttribute("match"); + var isAttributeChange = match != null && match.StartsWith("@"); + var index = match == null || isAttributeChange ? default(int?) : Int32.Parse(match) - 1; + var diffType = reader.LocalName; + var currentElement = stack.Peek(); + + if (currentElement.HasElements && index != null) { + var sourceElement = currentElement.Elements().ElementAt(index.Value); + stack.Push(sourceElement); + } + + if (diffType != "node") { + switch (diffType) { + case "change": + if (isAttributeChange) { + var attributeName = match.Substring(1); + var originalValue = currentElement.Attribute(attributeName).Value; + var currentValue = reader.ReadElementContentAsString(); + doRead = false; + yield return + new DiffNode { + Type = DiffType.Change, + ElementName = attributeName, + Previous = originalValue, + Current = currentValue + }; + } + else { + var originalContent = currentElement.Value; + var currentContent = reader.ReadElementContentAsString(); + stack.Pop(); + doRead = false; + yield return + new DiffNode { + Type = DiffType.Change, + ElementName = currentElement.Name.ToString(), + Previous = originalContent, + Current = currentContent + }; + } + break; + case "add": + reader.Read(); + var addedElementContent = reader.ReadElementContentAsString(); + yield return new DiffNode { Type = DiffType.Addition, ElementName = reader.Name, Current = addedElementContent }; + break; + } + } + break; + case XmlNodeType.EndElement: + stack.Pop(); + break; + } + if (doRead) + reader.Read(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs new file mode 100644 index 000000000..b7e88b108 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs @@ -0,0 +1,8 @@ +namespace Orchard.AuditTrail.Providers.Content { + public class DiffNode { + public DiffType Type { get; set; } + public string ElementName { get; set; } + public string Previous { get; set; } + public string Current { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffType.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffType.cs new file mode 100644 index 000000000..53eb53105 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffType.cs @@ -0,0 +1,6 @@ +namespace Orchard.AuditTrail.Providers.Content { + public enum DiffType { + Change, + Addition + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs new file mode 100644 index 000000000..13e0a55c5 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using System.Xml.Linq; + +namespace Orchard.AuditTrail.Providers.Content { + public interface IDiffGramAnalyzer : IDependency { + XElement GenerateDiffGram(XElement element1, XElement element2); + IEnumerable Analyze(XElement original, XElement diffGram); + } +} \ No newline at end of file From 363e1c9beb2cbbcee420c11f5c81254b7e986d20 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 20:12:18 +0200 Subject: [PATCH 025/116] Renaming a local variable. --- .../Providers/Content/DiffGramAnalyzer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index d1029b10c..49be713b7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -31,9 +31,7 @@ namespace Orchard.AuditTrail.Providers.Content { using (var reader = diffGram.CreateReader()) { while (!reader.EOF) { - var doRead = true; - if (reader.LocalName == "xmldiff") - reader.Read(); + var readNext = true; switch (reader.NodeType) { case XmlNodeType.Element: var match = reader.GetAttribute("match"); @@ -54,7 +52,8 @@ namespace Orchard.AuditTrail.Providers.Content { var attributeName = match.Substring(1); var originalValue = currentElement.Attribute(attributeName).Value; var currentValue = reader.ReadElementContentAsString(); - doRead = false; + + readNext = false; yield return new DiffNode { Type = DiffType.Change, @@ -66,8 +65,9 @@ namespace Orchard.AuditTrail.Providers.Content { else { var originalContent = currentElement.Value; var currentContent = reader.ReadElementContentAsString(); + stack.Pop(); - doRead = false; + readNext = false; yield return new DiffNode { Type = DiffType.Change, @@ -89,7 +89,7 @@ namespace Orchard.AuditTrail.Providers.Content { stack.Pop(); break; } - if (doRead) + if (readNext) reader.Read(); } } From f3cc944e75e8fc05944ca1533bb9762c7b7c56eb Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 20:14:19 +0200 Subject: [PATCH 026/116] Removing logic to manually get the previous version. We already get the previous version during the Published event, which will actually save a new version. --- .../Providers/Content/GlobalContentHandler.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 82e50b806..cd0ae04f4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -22,9 +22,7 @@ namespace Orchard.AuditTrail.Providers.Content { } protected override void Updated(UpdateContentContext context) { - var currentVersion = context.UpdatingItemVersionRecord; - var previousVersion = GetPreviousVersion(currentVersion); - RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem, previousVersion); + RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem); } protected override void Published(PublishContentContext context) { @@ -40,17 +38,6 @@ namespace Orchard.AuditTrail.Providers.Content { RecordAuditTrail(ContentAuditTrailEventProvider.Removed, context.ContentItem); } - private ContentItemVersionRecord GetPreviousVersion(ContentItemVersionRecord currentVersion) { - var number = currentVersion.Number; - var previousVersion = default(ContentItemVersionRecord); - - while (previousVersion == null) { - var contentItem = _contentManager.Get(currentVersion.ContentItemRecord.Id, VersionOptions.Number(--number)); - previousVersion = contentItem != null ? contentItem.VersionRecord : default(ContentItemVersionRecord); - } - return previousVersion; - } - private void RecordAuditTrail(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { var title = _contentManager.GetItemMetadata(content).DisplayText; From 3c159fbd9add7d81ab4d4a85f3b7435137badfab Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 20:14:43 +0200 Subject: [PATCH 027/116] Adding descriptive XML comments. --- .../Providers/Content/IDiffGramAnalyzer.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs index 13e0a55c5..7482dd681 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs @@ -3,7 +3,15 @@ using System.Xml.Linq; namespace Orchard.AuditTrail.Providers.Content { public interface IDiffGramAnalyzer : IDependency { + /// + /// Compares the specified XML elements and returns a DiffGram XML element. + /// XElement GenerateDiffGram(XElement element1, XElement element2); + + /// + /// Analyzes the specified DiffGram against the specified original XML element and returns a list of diff nodes, + /// where each node describes the difference between the original and updated document. + /// IEnumerable Analyze(XElement original, XElement diffGram); } } \ No newline at end of file From b48686dfe1bb0bfce3f72dbd14321e1afbe65419 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 20:15:19 +0200 Subject: [PATCH 028/116] Updating Content Audit Trail Event view with diff gram, if available. --- .../Views/AuditTrailEvent-Content.cshtml | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index ccea5eb2c..323bc0b56 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -1,7 +1,9 @@ -@using Orchard.ContentManagement +@using Orchard.AuditTrail.Providers.Content +@using Orchard.ContentManagement @{ var contentItem = (ContentItem) Model.ContentItem; var previousVersion = (ContentItem) Model.PreviousVersion; + var diffNodes = (IEnumerable) Model.DiffNodes; }
@@ -13,4 +15,33 @@ @T("Previous version:") @Html.ItemEditLink(previousVersion)
+ + + + + + + + + + + + @if (!diffNodes.Any()) { + + + + } + else { + foreach (var node in diffNodes) { + + + + + + + } + } + +
@T("Diff Type")@T("Element")@T("Before")@T("After")
@T("")
@T(node.Type.ToString())@node.ElementName@node.Previous@node.Current
+ } \ No newline at end of file From 2037a0dafa4fbc555d4009c34283e8ed66996c25 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 20:58:12 +0200 Subject: [PATCH 029/116] Introducing Audit Trail Trimming feature and extracting trimming settings. --- ...ver.cs => AuditTrailSettingsPartDriver.cs} | 18 ++++----- .../AuditTrailTrimmingSettingsPartDriver.cs | 40 +++++++++++++++++++ ...er.cs => AuditTrailSettingsPartHandler.cs} | 13 +++--- .../AuditTrailTrimmingSettingsPartHandler.cs | 23 +++++++++++ .../Modules/Orchard.AuditTrail/Migrations.cs | 6 --- .../Models/AuditTrailSettingsPart.cs | 14 +++++++ .../Models/AuditTrailSiteSettingsPart.cs | 27 ------------- .../Models/AuditTrailTrimmingSettingsPart.cs | 13 ++++++ .../Modules/Orchard.AuditTrail/Module.txt | 7 +++- .../Orchard.AuditTrail.csproj | 15 ++++--- .../Modules/Orchard.AuditTrail/Placement.info | 3 +- .../Services/AuditTrailManager.cs | 2 +- .../ViewModels/AuditTrailSettingsViewModel.cs | 7 ++++ .../AuditTrailSiteSettingsViewModel.cs | 10 ----- .../AuditTrailTrimmingSettingsViewModel.cs | 5 +++ ...cshtml => Parts.AuditTrailSettings.cshtml} | 15 +------ .../Parts.AuditTrailTrimmingSettings.cshtml | 9 +++++ 17 files changed, 145 insertions(+), 82 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/{AuditTrailSiteSettingsPartDriver.cs => AuditTrailSettingsPartDriver.cs} (75%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs rename src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/{AuditTrailSiteSettingsPartHandler.cs => AuditTrailSettingsPartHandler.cs} (84%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSettingsPart.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSettingsViewModel.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/{Parts.AuditTrailSiteSettings.cshtml => Parts.AuditTrailSettings.cshtml} (70%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs similarity index 75% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index 9e536b4e6..5a49b941f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSiteSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -7,29 +7,27 @@ using Orchard.ContentManagement.Drivers; using Orchard.Security; namespace Orchard.AuditTrail.Drivers { - public class AuditTrailSiteSettingsPartDriver : ContentPartDriver { + public class AuditTrailSettingsPartDriver : ContentPartDriver { private readonly IAuditTrailManager _auditTrailManager; private readonly IAuthorizer _authorizer; - public AuditTrailSiteSettingsPartDriver(IAuditTrailManager auditTrailManager, IAuthorizer authorizer) { + public AuditTrailSettingsPartDriver(IAuditTrailManager auditTrailManager, IAuthorizer authorizer) { _auditTrailManager = auditTrailManager; _authorizer = authorizer; } - protected override DriverResult Editor(AuditTrailSiteSettingsPart part, dynamic shapeHelper) { + protected override DriverResult Editor(AuditTrailSettingsPart part, dynamic shapeHelper) { return Editor(part, null, shapeHelper); } - protected override DriverResult Editor(AuditTrailSiteSettingsPart part, IUpdateModel updater, dynamic shapeHelper) { + protected override DriverResult Editor(AuditTrailSettingsPart part, IUpdateModel updater, dynamic shapeHelper) { if (!_authorizer.Authorize(Permissions.ManageAuditTrailSettings)) return null; - return ContentShape("Parts_AuditTrailSiteSettings_Edit", () => { + return ContentShape("Parts_AuditTrailSettings_Edit", () => { var descriptors = _auditTrailManager.Describe(); var eventSettings = part.EventSettings.ToList(); - var viewModel = new AuditTrailSiteSettingsViewModel { - AutoTrim = part.AutoTrim, - AutoTrimThreshold = part.AutoTrimThreshold, + var viewModel = new AuditTrailSettingsViewModel { Categories = (from categoryDescriptor in descriptors select new AuditTrailCategorySettingsViewModel { Category = categoryDescriptor.Category, @@ -58,12 +56,10 @@ namespace Orchard.AuditTrail.Drivers { eventSetting.IsEnabled = eventSettingViewModel.IsEnabled; } part.EventSettings = eventSettings; - part.AutoTrim = viewModel.AutoTrim; - part.AutoTrimThreshold = viewModel.AutoTrimThreshold; } } - return shapeHelper.EditorTemplate(TemplateName: "Parts.AuditTrailSiteSettings", Model: viewModel, Prefix: Prefix); + return shapeHelper.EditorTemplate(TemplateName: "Parts.AuditTrailSettings", Model: viewModel, Prefix: Prefix); }).OnGroup("Audit Trail"); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs new file mode 100644 index 000000000..1d50a7772 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -0,0 +1,40 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.ViewModels; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; +using Orchard.Environment.Extensions; +using Orchard.Security; + +namespace Orchard.AuditTrail.Drivers { + [OrchardFeature("Orchard.AuditTrail.Trimming")] + public class AuditTrailTrimmingSettingsPartDriver : ContentPartDriver { + private readonly IAuthorizer _authorizer; + + public AuditTrailTrimmingSettingsPartDriver(IAuthorizer authorizer) { + _authorizer = authorizer; + } + + protected override DriverResult Editor(AuditTrailTrimmingSettingsPart part, dynamic shapeHelper) { + return Editor(part, null, shapeHelper); + } + + protected override DriverResult Editor(AuditTrailTrimmingSettingsPart part, IUpdateModel updater, dynamic shapeHelper) { + if (!_authorizer.Authorize(Permissions.ManageAuditTrailSettings)) + return null; + + return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { + var viewModel = new AuditTrailTrimmingSettingsViewModel { + AutoTrimThreshold = part.AutoTrimThreshold, + }; + + if (updater != null) { + if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { + part.AutoTrimThreshold = viewModel.AutoTrimThreshold; + } + } + + return shapeHelper.EditorTemplate(TemplateName: "Parts.AuditTrailTrimmingSettings", Model: viewModel, Prefix: Prefix); + }).OnGroup("Audit Trail"); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs similarity index 84% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs index 4a41b300e..8a34f02d2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSiteSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs @@ -10,23 +10,24 @@ using Orchard.Localization; using Orchard.Logging; namespace Orchard.AuditTrail.Handlers { - public class AuditTrailSiteSettingsPartHandler : ContentHandler { + public class AuditTrailSettingsPartHandler : ContentHandler { private readonly ISignals _signals; - public AuditTrailSiteSettingsPartHandler(ISignals signals) { + public AuditTrailSettingsPartHandler(ISignals signals) { _signals = signals; - OnActivated(SetupLazyFields); - OnGetContentItemMetadata(GetMetadata); + Filters.Add(new ActivatingFilter("Site")); + OnActivated(SetupLazyFields); + OnGetContentItemMetadata(GetMetadata); T = NullLocalizer.Instance; } public Localizer T { get; set; } - private void GetMetadata(GetContentItemMetadataContext context, AuditTrailSiteSettingsPart part) { + private void GetMetadata(GetContentItemMetadataContext context, AuditTrailSettingsPart part) { context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Audit Trail"))); } - private void SetupLazyFields(ActivatedContentContext context, AuditTrailSiteSettingsPart part) { + private void SetupLazyFields(ActivatedContentContext context, AuditTrailSettingsPart part) { part._eventProviderSettingsField.Loader(() => DeserializeProviderConfiguration(part.Retrieve("Events"))); part._eventProviderSettingsField.Setter(value => { part.Store("Events", SerializeProviderConfiguration(value)); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs new file mode 100644 index 000000000..7bee7cc4e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs @@ -0,0 +1,23 @@ +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Handlers; +using Orchard.Environment.Extensions; +using Orchard.Localization; + +namespace Orchard.AuditTrail.Handlers { + [OrchardFeature("Orchard.AuditTrail.Trimming")] + public class AuditTrailTrimmingSettingsPartHandler : ContentHandler { + + public AuditTrailTrimmingSettingsPartHandler() { + Filters.Add(new ActivatingFilter("Site")); + OnGetContentItemMetadata(GetMetadata); + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + + private void GetMetadata(GetContentItemMetadataContext context, AuditTrailSettingsPart part) { + context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Audit Trail"))); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs index 8da58b6cd..f399c1756 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -22,12 +22,6 @@ namespace Orchard.AuditTrail { .Attachable() .WithDescription("Enables the user to enter a comment about the change when saving a content item.")); - ContentDefinitionManager.AlterPartDefinition("AuditTrailSiteSettingsPart", part => part - .Attachable(false) - .WithDescription("Stores the audit trail settings.")); - - ContentDefinitionManager.AlterTypeDefinition("Site", type => type.WithPart("AuditTrailSiteSettingsPart")); - return 1; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSettingsPart.cs new file mode 100644 index 000000000..012f47134 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSettingsPart.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.Core.Common.Utilities; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailSettingsPart : ContentPart { + internal LazyField> _eventProviderSettingsField = new LazyField>(); + + public IEnumerable EventSettings { + get { return _eventProviderSettingsField.Value; } + set { _eventProviderSettingsField.Value = value; } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs deleted file mode 100644 index e982f7562..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailSiteSettingsPart.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using Orchard.ContentManagement; -using Orchard.Core.Common.Utilities; - -namespace Orchard.AuditTrail.Models { - public class AuditTrailSiteSettingsPart : ContentPart { - internal LazyField> _eventProviderSettingsField = new LazyField>(); - - public bool AutoTrim { - get { return this.Retrieve(x => x.AutoTrim, defaultValue: false); } - set { this.Store(x => x.AutoTrim, value); } - } - - /// - /// Threshold in days. - /// - public int AutoTrimThreshold { - get { return this.Retrieve(x => x.AutoTrimThreshold, defaultValue: 10); } - set { this.Store(x => x.AutoTrimThreshold, value); } - } - - public IEnumerable EventSettings { - get { return _eventProviderSettingsField.Value; } - set { _eventProviderSettingsField.Value = value; } - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs new file mode 100644 index 000000000..f0bec8e92 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs @@ -0,0 +1,13 @@ +using Orchard.ContentManagement; + +namespace Orchard.AuditTrail.Models { + public class AuditTrailTrimmingSettingsPart : ContentPart { + /// + /// Threshold in days. + /// + public int AutoTrimThreshold { + get { return this.Retrieve(x => x.AutoTrimThreshold, defaultValue: 10); } + set { this.Store(x => x.AutoTrimThreshold, value); } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 8a2564d11..1d50d3a86 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -10,4 +10,9 @@ Features: Name: AuditTrail Description: Provides the core audit trail framework. Category: Security - Dependencies: Orchard.Users, Orchard.Roles, Orchard.ContentTypes \ No newline at end of file + Dependencies: Orchard.Users, Orchard.Roles, Orchard.ContentTypes + Orchard.AuditTrail.Trimming: + Name: AuditTrail Trimming + Description: A background task that trims the audit trail. + Category: Security + Dependencies: Orchard.AuditTrail \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 0bc6645e7..3e24d6c65 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -108,7 +108,7 @@ - + @@ -126,6 +126,7 @@ +
@@ -140,11 +141,14 @@ - + + + + @@ -152,11 +156,12 @@ - + + - + - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info index baff8c89c..ae18bc77f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -2,7 +2,8 @@ + Parts_AuditTrailTrimmingSettings_Edit="Content:0" + Parts_AuditTrailSettings_Edit="Content:1"/> diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index be8020858..e33b46f6c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -121,7 +121,7 @@ namespace Orchard.AuditTrail.Services { private bool IsEnabled(AuditTrailEventDescriptor eventDescriptor) { var settingsDictionary = _cacheManager.Get("AuditTrail.EventSettings", context => { context.Monitor(_signals.When("AuditTrail.EventSettings")); - return _siteService.GetSiteSettings().As().EventSettings.ToDictionary(x => x.EventName); + return _siteService.GetSiteSettings().As().EventSettings.ToDictionary(x => x.EventName); }); var setting = settingsDictionary.ContainsKey(eventDescriptor.Event) ? settingsDictionary[eventDescriptor.Event] : default(AuditTrailEventSetting); return setting != null ? setting.IsEnabled : eventDescriptor.IsEnabledByDefault; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSettingsViewModel.cs new file mode 100644 index 000000000..12711762d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSettingsViewModel.cs @@ -0,0 +1,7 @@ +using System.Collections.Generic; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailSettingsViewModel { + public IList Categories { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs deleted file mode 100644 index 6a2ba0aa9..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailSiteSettingsViewModel.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace Orchard.AuditTrail.ViewModels { - public class AuditTrailSiteSettingsViewModel { - public bool AutoTrim { get; set; } - public int AutoTrimThreshold { get; set; } - public IList Categories { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs new file mode 100644 index 000000000..c5bd20a51 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -0,0 +1,5 @@ +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailTrimmingSettingsViewModel { + public int AutoTrimThreshold { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml similarity index 70% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index 9100d388b..ed01c5791 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSiteSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -1,21 +1,8 @@ -@model Orchard.AuditTrail.ViewModels.AuditTrailSiteSettingsViewModel +@model Orchard.AuditTrail.ViewModels.AuditTrailSettingsViewModel @{ Style.Include("admin.css"); }
-
- @T("Auto Trim Settings") -
- @Html.CheckBoxFor(m => m.AutoTrim) - @Html.LabelFor(m => m.AutoTrim, T("Automatically trim the audit trail for this site").Text, new { @class = "forcheckbox" }) - @T("Check this option to automatically trim the audit trail.") -
-
- @Html.LabelFor(m => m.AutoTrimThreshold, T("Auto-trim threshold")) - @Html.TextBoxFor(m => m.AutoTrimThreshold, new { @class = "text small" }) - @T("Specify the number of days of audit log data to retain.") -
-
@T("Specify the events to audit") @{ diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml new file mode 100644 index 000000000..3f2ad0c13 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -0,0 +1,9 @@ +@model Orchard.AuditTrail.ViewModels.AuditTrailTrimmingSettingsViewModel +
+ @T("Auto Trim Settings") +
+ @Html.LabelFor(m => m.AutoTrimThreshold, T("Auto-trim threshold")) + @Html.TextBoxFor(m => m.AutoTrimThreshold, new { @class = "text small" }) + @T("Specify the number of days of audit log data to retain.") +
+
\ No newline at end of file From 7c1c64eb90ad539727c1b0eb878efd2d9579b5b3 Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 22:03:23 +0200 Subject: [PATCH 030/116] Implementing trimming background task. --- .../AuditTrailTrimmingSettingsPartDriver.cs | 4 +- .../Models/AuditTrailTrimmingSettingsPart.cs | 17 ++++-- .../Orchard.AuditTrail.csproj | 1 + .../Services/AuditTrailManager.cs | 13 ++++ .../AuditTrailTrimmingBackgroundTask.cs | 61 +++++++++++++++++++ .../Services/IAuditTrailManager.cs | 6 ++ .../AuditTrailTrimmingSettingsViewModel.cs | 2 +- .../Parts.AuditTrailTrimmingSettings.cshtml | 4 +- 8 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 1d50a7772..0b3bb77a8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -24,12 +24,12 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { var viewModel = new AuditTrailTrimmingSettingsViewModel { - AutoTrimThreshold = part.AutoTrimThreshold, + Threshold = part.Threshold, }; if (updater != null) { if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { - part.AutoTrimThreshold = viewModel.AutoTrimThreshold; + part.Threshold = viewModel.Threshold; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs index f0bec8e92..a9e36944d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs @@ -1,13 +1,22 @@ -using Orchard.ContentManagement; +using System; +using Orchard.ContentManagement; namespace Orchard.AuditTrail.Models { public class AuditTrailTrimmingSettingsPart : ContentPart { /// /// Threshold in days. /// - public int AutoTrimThreshold { - get { return this.Retrieve(x => x.AutoTrimThreshold, defaultValue: 10); } - set { this.Store(x => x.AutoTrimThreshold, value); } + public int Threshold { + get { return this.Retrieve(x => x.Threshold, defaultValue: 10); } + set { this.Store(x => x.Threshold, value); } + } + + /// + /// The timestamp the audit trail was last trimmed. + /// + public DateTime? LastRunUtc { + get { return this.Retrieve(x => x.LastRunUtc); } + set { this.Store(x => x.LastRunUtc, value); } } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 3e24d6c65..5f896b04f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -154,6 +154,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index e33b46f6c..533835b49 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; using Orchard.Caching; @@ -152,5 +153,17 @@ namespace Orchard.AuditTrail.Services { return eventDescriptors.First(); } + + public IEnumerable Trim(TimeSpan threshold) { + var dateThreshold = _clock.UtcNow.Date - threshold; + var query = _auditTrailRepository.Table.Where(x => x.CreatedUtc < dateThreshold); + var records = query.ToArray(); + + foreach (var record in records) { + _auditTrailRepository.Delete(record); + } + + return records; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs new file mode 100644 index 000000000..9ed5e1a42 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -0,0 +1,61 @@ +using System; +using System.Linq; +using System.Threading; +using Orchard.AuditTrail.Models; +using Orchard.ContentManagement; +using Orchard.Environment.Extensions; +using Orchard.Logging; +using Orchard.Services; +using Orchard.Settings; +using Orchard.Tasks; + +namespace Orchard.AuditTrail.Services { + [OrchardFeature("Orchard.AuditTrail.Trimming")] + public class AuditTrailTrimmingBackgroundTask : Component, IBackgroundTask { + private static readonly object _sweepLock = new object(); + private readonly ISiteService _siteService; + private readonly IClock _clock; + private readonly IAuditTrailManager _auditTrailManager; + + public AuditTrailTrimmingBackgroundTask(ISiteService siteService, IClock clock, IAuditTrailManager auditTrailManager) { + _siteService = siteService; + _clock = clock; + _auditTrailManager = auditTrailManager; + } + + public AuditTrailTrimmingSettingsPart Settings { + get { return _siteService.GetSiteSettings().As(); } + } + + public void Sweep() { + if (Monitor.TryEnter(_sweepLock)) { + try { + Logger.Debug("Beginning sweep."); + + // We don't need to check the audit trail for events to remove every minute. Let's stick with twice a day. + if (!TimeToTrim()) + return; + + Logger.Debug("Starting audit trail trimming operation."); + var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.Threshold)); + Logger.Debug("Audit trail trimming operation completed. {0} Records were deleted.", deletedRecords.Count()); + Settings.LastRunUtc = _clock.UtcNow; + } + catch (Exception ex) { + Logger.Error(ex, "Error during sweep."); + } + finally { + Monitor.Exit(_sweepLock); + Logger.Debug("Ending sweep."); + } + } + } + + private bool TimeToTrim() { + var lastRun = Settings.LastRunUtc ?? DateTime.MinValue; + var now = _clock.UtcNow; + var interval = TimeSpan.FromHours(12); + return now - lastRun > interval; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 3039c0be7..91e1d1812 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -56,5 +56,11 @@ namespace Orchard.AuditTrail.Services { /// The fully qualified event name to describe. /// Returns a single audit trail event descriptor. AuditTrailEventDescriptor Describe(string fullyQualifiedEventName); + + /// + /// Trims the audit trail by deleting all records older than the specified threshold. + /// + /// Returns the deleted records. + IEnumerable Trim(TimeSpan threshold); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs index c5bd20a51..d13d6920e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -1,5 +1,5 @@ namespace Orchard.AuditTrail.ViewModels { public class AuditTrailTrimmingSettingsViewModel { - public int AutoTrimThreshold { get; set; } + public int Threshold { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index 3f2ad0c13..afb4a8df5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -2,8 +2,8 @@
@T("Auto Trim Settings")
- @Html.LabelFor(m => m.AutoTrimThreshold, T("Auto-trim threshold")) - @Html.TextBoxFor(m => m.AutoTrimThreshold, new { @class = "text small" }) + @Html.LabelFor(m => m.Threshold, T("Auto-trim threshold")) + @Html.TextBoxFor(m => m.Threshold, new { @class = "text small" }) @T("Specify the number of days of audit log data to retain.")
\ No newline at end of file From de90b6060397770352b15d25f81cec9557f458fa Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 22:29:34 +0200 Subject: [PATCH 031/116] Adding LoginFailed event. [Core Module Change] --- .../Modules/Orchard.Users/Controllers/AccountController.cs | 1 + .../Modules/Orchard.Users/Events/IUserEventHandler.cs | 5 +++++ .../Orchard.Users/Handlers/WorkflowUserEventHandler.cs | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs index 1dc2dc554..9d1f9d3ce 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs @@ -346,6 +346,7 @@ namespace Orchard.Users.Controllers { var user = _membershipService.ValidateUser(userNameOrEmail, password); if (user == null) { + _userEventHandler.LogInFailed(userNameOrEmail, password); ModelState.AddModelError("_FORM", T("The username or e-mail or password provided is incorrect.")); } diff --git a/src/Orchard.Web/Modules/Orchard.Users/Events/IUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Users/Events/IUserEventHandler.cs index 880d8878a..6f5b56c6e 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Events/IUserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Events/IUserEventHandler.cs @@ -23,6 +23,11 @@ namespace Orchard.Users.Events { ///
void LoggedIn(IUser user); + /// + /// Called when a login attempt failed + /// + void LogInFailed(string userNameOrEmail, string password); + /// /// Called when a user explicitly logs out (as opposed to one whose session cookie simply expires) /// diff --git a/src/Orchard.Web/Modules/Orchard.Users/Handlers/WorkflowUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Users/Handlers/WorkflowUserEventHandler.cs index 9df2fe061..0164c86e1 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Handlers/WorkflowUserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Handlers/WorkflowUserEventHandler.cs @@ -36,6 +36,12 @@ namespace Orchard.Users.Handlers { () => new Dictionary {{"User", user}}); } + public void LogInFailed(string userNameOrEmail, string password) { + _workflowManager.TriggerEvent("UserLogInFailed", + null, + () => new Dictionary { { "UserNameOrEmail", userNameOrEmail }, { "Password", password } }); + } + public void LoggedOut(Security.IUser user) { _workflowManager.TriggerEvent("UserLoggedOut", user, From 138fe3da4fd7ed7a71cb618a20cbe189183b474d Mon Sep 17 00:00:00 2001 From: sfmskywalker Date: Mon, 2 Jun 2014 22:30:25 +0200 Subject: [PATCH 032/116] Adding events to user audit trail event provider. --- .../Orchard.AuditTrail.csproj | 1 + .../Providers/User/IUserEventHandler.cs | 18 +++++++++++++++++- .../User/UserAuditTrailEventProvider.cs | 6 ++++++ .../Providers/User/UserEventHandler.cs | 19 +++++++++++++++++-- .../AuditTrailEvent-User-LoginFailed..cshtml | 9 +++++++++ .../AuditTrailEvent-User.SummaryAdmin.cshtml | 2 +- .../Views/AuditTrailEvent-User.cshtml | 2 +- 7 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 5f896b04f..85063aaae 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -127,6 +127,7 @@ +
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs index bf66c0a24..be189b1c1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs @@ -3,8 +3,24 @@ using Orchard.Security; namespace Orchard.AuditTrail.Providers.User { public interface IUserEventHandler : IEventHandler { + /// - /// Called after a user has changed password + /// Called after a user has logged in. + /// + void LoggedIn(IUser user); + + /// + /// Called when a user explicitly logs out (as opposed to one whose session cookie simply expires). + /// + void LoggedOut(IUser user); + + /// + /// Called when a login attempt failed. + /// + void LogInFailed(string userNameOrEmail, string password); + + /// + /// Called after a user has changed password. /// void ChangedPassword(IUser user); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs index 738874524..7586775b9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs @@ -3,10 +3,16 @@ using Orchard.AuditTrail.Services; namespace Orchard.AuditTrail.Providers.User { public class UserAuditTrailEventProvider : AuditTrailEventProviderBase { + public const string LoggedIn = "LoggedIn"; + public const string LoggedOut = "LoggedOut"; + public const string LogInFailed = "LogInFailed"; public const string PasswordChanged = "PasswordChanged"; public override void Describe(DescribeContext context) { context.For("User", T("User")) + .Event(this, LoggedIn, T("Logged in"), T("A user was successfully logged in."), enableByDefault: true) + .Event(this, LoggedOut, T("Logged out"), T("A user explicitly logged out."), enableByDefault: true) + .Event(this, LogInFailed, T("Login failed"), T("An attempt to login failed due to an incorrect username/email and/or password."), enableByDefault: true) .Event(this, PasswordChanged, T("Password changed"), T("A user's password was changed."), enableByDefault: true); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs index 759f319dc..bd5fe80b0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Globalization; using Orchard.AuditTrail.Services; using Orchard.Security; @@ -13,6 +12,22 @@ namespace Orchard.AuditTrail.Providers.User { _wca = wca; } + public void LoggedIn(IUser user) { + RecordAuditTrail(UserAuditTrailEventProvider.LoggedIn, user); + } + + public void LoggedOut(IUser user) { + RecordAuditTrail(UserAuditTrailEventProvider.LoggedOut, user); + } + + public void LogInFailed(string userNameOrEmail, string password) { + var eventData = new Dictionary { + {"UserName", userNameOrEmail} + }; + + _auditTrailManager.Record(UserAuditTrailEventProvider.LogInFailed, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "user", eventFilterData: userNameOrEmail); + } + public void ChangedPassword(IUser user) { RecordAuditTrail(UserAuditTrailEventProvider.PasswordChanged, user); } @@ -28,7 +43,7 @@ namespace Orchard.AuditTrail.Providers.User { {"UserName", user.UserName} }; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.Id.ToString(CultureInfo.InvariantCulture)); + _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.UserName); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml new file mode 100644 index 000000000..cc4093253 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var userName = eventData.Get("UserName"); +} + +
+ @T("Attempted user name: {0}", userName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml index 9a09f35fd..5d64628ea 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml @@ -5,5 +5,5 @@ }
- @userName + @T("User: {0}", userName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml index 9a09f35fd..5d64628ea 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml @@ -5,5 +5,5 @@ }
- @userName + @T("User: {0}", userName)
\ No newline at end of file From e658ae29f995125e4bb55c33762ece27b2b14667 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 17 Jun 2014 08:08:34 -0700 Subject: [PATCH 033/116] Adding missing assembly. --- .../Lib/XmlDiffPatch/xmldiffpatch.dll | Bin 0 -> 100912 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Lib/XmlDiffPatch/xmldiffpatch.dll diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Lib/XmlDiffPatch/xmldiffpatch.dll b/src/Orchard.Web/Modules/Orchard.AuditTrail/Lib/XmlDiffPatch/xmldiffpatch.dll new file mode 100644 index 0000000000000000000000000000000000000000..916dd2b652740da655f44df78c59f950a1473be2 GIT binary patch literal 100912 zcmeFaePCQg)jvM>W$(RvcQ?t+Zg!KVZPL<|ZFV<(2`_02G(f9R3$(OA%A2K>w_4be zq`Yl|twrRa1raJ@1*sL0M^I4_QBaTqqT(YeC?N8H76rj~R37E!_c`ax-MyQ%$n*92 z@5i>8J7?z1nRCvZdA&1pk2wA+Whtd>{Jr_6Qg`7=zkYV#+S!2UhK_GEs5|06m~@x1 z=m(RQoq5(!=i0&Y8H1;s-FfOM=bTd>?p%3V=is_?I?p<%bN*3FJI^k!I;|&_@~3Fh zix()h$gtGYo6b2f%O~N+?5dZw!j(CLoohHl0 z0N~n_eS!*kGt+81}z;b}HpX@IAnXMc|&{(=HeWylR$~ zt6%tzppb|wdIpCEPemZ}1|CT^wHVLHuOFJ~89Z%G8Hmg)cxF7pkNkjlNCbSx`;G?Q z(ZD+zct->8Xy6?UyrY44H1LiF-qFB28hA$o|3A_|Kh3N0qq(Vxzxm%%>b`4~ic?_Z zx408i;Rw7Z?{(7-c>UqdzFA%W^@kM?eQV^!U;O#S3%@Zw_1*tmvvj|o|MZQASIl@M z|LCCyUG-mgto`rL-t=Z{+iG`s_Pl4me0KKPUDK{}7wjC^cJkI;XRY1w-MPOyduMv- z-&&eimj)i&vhs`v*ZYf)Z$0|2Yrpv8zrTLe{m;Gm+CBUHbJ_Xx-ZH zjucIT=1am)7hT87V?oH#LYIGCm6vHa>OFYU&n#!^Q%cFE|rY|epkG-@~DprH7-8=eqvsqu&<9)xAT z(CAop8OG)~OwV^pzh^paz=NG>ymhE4R6w3%mFEMwJ1h0cR5d(eGm3`=z6jnl&_h86 zmbN=H3o%Jk>rmNVh{|Y@BI$^}TjRs8@iBJ~c+5ux?|?cyUJ?XNGrKwux(*5m zV%np12UhKowb_ARl~Pv?QZShS>#*@r;MUQ z;C~bR2ZE`}T7!Rw*Q`+fl{?^+p9Z-^vyq3;zD7wIAximsh}EGJs-YDu+}cHVa3(?u zvBCZEU>p+$K!m9&bj%9L;1?QDd_#bp3W{1GH4 zt4I0M17&5K*%62hXb5%B89_y{b%Se-p!a~r%GV(x`-U-sQULnukp!OIRA+3p6ZC-v zqpuKh-;s33Tv+r@~v2B6#-gENpqD|)ampPCEj?#eNRf#` z+H!}^3nSgi6bf`pzcnkQ?j)kUAy|*3^(shfC%w{dQBJn{1oDMigREb;*sKtPteb?J zTfP8=&3!sDQM8m@!XK4uKmH1fP0PuHF9#{-o0c8RgJ;Jt^qCcs-kxrB!?3}Zf<$PVN0&UNijZmTS_?dwxw-J z5@+rXJdAoHP7~M?vL8as3RTJC3^SYG3-Rfg71+5THiTCzjxZP4K}@Ic@=&$YcN;W> zke|Sx>wS+|$$~=K37o(l*%w}ue8c;IcAVY(R3HWpx7j7jF0Qo#O*+yLWSh*wadxp8 z*>mf_c~jsaX2l25(j1**cKQs9Nu}MuU5AQpmYU%Kj#-Ms1JgE(sX8*IW?z?xDGC8Z z1@A}|cO`InZb0g~=rw!bGmsVanu>wTk!y6f*~O+C66|8*ttSYG+6+x+1~pstM6~9Y zgqn|sDt*I13z+tycRz@8L8Lv1K#=Fy~k)~z*2iAJGOBNTY7 zy`opehlFJJHf#2FJFq+6 zSiS(H)S>z>u-khMLhxz5hq=S(dd;L)J{-fT?CRc>r-d&sM1bX$-;GC3qH7jd*w=Ei ztB3Xj^DJPY%W`R~?3Bh+gtYcy&oR^&qM5>ISSnSBWD!Y3u7mywM#q#+-}5At&NhYe zCR+(Di|8r#XeIKRZ!fv z^f(fWUIm>Vnb!#QOd%R2VtbXs$@QkpxGPn1Z)96-eW-pFQP$KF!1ORgOV4oCpU^r$ z%b`7h7}*1LcuocVH`~KPJheT7gRkD`6%tt}AN1qh8P2G-0nH1g+fDM_ z*orPEX#mhIutakq5h{!1nHvb7(hxu(;!f(R^r6xjv6Xdm%At9{NV{g>?h%<91}ku- z{eV=|2fc;@MePsEA2wDi|3wgK8@fPg9gZL<`BrV>nCg|$mN5IX$j#GTNx}>3TOkMU zZYp-FPD3`8HED*}5tp?hVoJcQ22UFraXB4^$6c_XNEE9|^U!ZXYK`O7s!HEWU=t=8 z(>!g5zDh@j)#`AmRB1<2pks2%E?P1ulpe&BUz~z&vFuT(Q;tg{LoP#kjNs7uh7`+A z~xXV3as*rHKHgwHsbQ~yx%Kh!j$m35fJIke|qrSP&SAyp)u5XocGP-xR(0E?lG8!bG=K!vH z6=~581liR-Mx&_iesQf0`PgS=S9gcw{XVyXWVR)?w3l1y1Y`@;;#Qy!495|Mbq}|K zft=l4ofJH1w(`)>Ge0$)O3d~u80LpLPw^@k zxQ01ry$a-_G?KMf!Fbv3u1+`}Fmqwn4Yq~6(fHa!7#TV|Ep%XCW_7QO@WHb-9s^%w zDq5Ed>>%`s@Oa+ zEN=%!vDGQJFcP_pR64S+jS10WkIU;x624zlMQMlEg_@?c<+vS9XweQQ zhCDcZ-#}=DR&j!?T1D~#qhAJ6-&JtNWYm=`?YEm0#nVj*4HF3ew5r9;N~&$w z_*bcBiApO6F~)F0}12y;Cf@bAI{yn{O7Tglsf|4HN+Ne`EM?N>3KX)ekJA+_4kQPMCgrcB1C0#C=s=Z-$WX;IDwVb+4~j`f_Qy3(YFoJV!9X=_rLY1*l}e% ztnKDH$bvE2(7_~A98TeIxBMiY#qoN~m2sjYF2U)7J)_=Z;Ny%PF;_{6{0Vo?3QWRv z`x;X(fLXMCkVT}%n$J%_D%V@ExFeBzSr|u@MJ>eEC|yRxPxf66iqhXg{63E-1z1WC zCk657_|A#Tq(Gu&QXpb`T5OLeAw`Jo$v|@&vJb`P#c>jQ_u~mh^VpV?-kdX8Y%0Gq zz#+OIJ@y%vRRHe8FbO&a%@JnXG7>%(fQ-0C&HJ$mKx1(pe|zzn859c5{mu0>OpojN ze>mbIJDY_((E}k*$fsAYOthH<@gkr0eid-O2pMb3Nw7IbEd+VA&6pTIfk;2bk3=Tf zmq&y%y92H}`!8rc9jwL^(eiWfr{bk1tn0YVW*!VUefJXrzY8d1%!6Y57GaWip!I~b zy%(6ouc<$<*HAC)AFo6HIB(#rwC$#2PTGm5-FVt_%TFOyI_}65>lgQeR5~G+kxpjQ zslFe9R*)<%2;AbqP5`A=`ARojyawn&!&Z5^Tc`U$1BO<~bga-4#DgT09Z16`gp)x6 zguLRxZh(<#jZmWyXw-x}BGj1nf<)Q@AwNiHLhxx0!Oc-1gq01ZLRGFf1#C8e#XM$< zPIkJLNmG6e$g38T2vWI$bSg*%_Vk7zIcGBLDM-v|r-xhGFYrnez_@?F?T{MlVV3LV zF?et?m@ScN5^fOdeKA@X`=UESs(hi5mfm`RD@yb+i0pkilZ@hGOsPUurJKa(ZA}M3 zQxMGRB)7Mha-Uw>W7dJ2D&%&TQ{biI>E@uhZTSN9;JiWzOXU^9(N8R+s?mSPle}v{ znA-~(EXVURS@gm(Ga8&PA+%WB18yFM8b>R0IFPvNW|D=>SUnbIYc*-T7N(6Bs`UFp z%h+^o=_O~*k6(N9O?S>CaJl`r)MZdCMmbn7%_g$RY|7$6y)8p~3{d*j_+DO5DH>D^ZIvRsIcVN(i zX%;6T8I55O$U_-UM(-s3f*;QfqzX2VI_VU< z?6>S|q>o9WtH4TuEgfdNWqXl!pswqczWy)Z1sz0$7g@0^LOtD9Oja|Ahr)PSxGZI? zbvBBjn2g5mMu2HZR29G}9sn8MmH?Q&$wFGKyX==?1LN(zjTYw7way#w z2Y{-ybwOhzurXx^DV5_su0QCVh0;bfipTQZm$gVT{HF!+jSG zFgrm5Gl_>0SB%RduwPh|T^%;&+lirBQtx7siFJo*^Ss*TiFAzpvD&0MVaM8BZZUjt z5#z<^QS8MzBFYr?$IHOeB$BIMmZ_SxJ&V*}XO?JvV|>%tU`wG@&?wkTx&bcXc@OND ze|R~@lhcgMFtaix&5odD)q4+21>OW#_9s{)Gzr7YM4Ek>u@R86%?5jfW?yDQYy`z2 z?;Xda>m&?&1aeV2bl{v0eK@DXBE;zTmEo(-E{fvu@W){^NQl?}r_xKwd3bMFdsAsv z2$2Vfv}i|b!7wD%40}Hnf0L0G<52Y#{C(C`>Mv+pPqic*M>^CI2qT=)e|I4c)K<-1 ziUfTbU|54N@wK_M)6A0`dFd&+ufqh>#5>X@K#+wPey=I3FOeMrkN}fHpwK#uMxm9N zdX!Tbg~H|SXay|7&U>=fU>Q;7dV*{3U9o1tFHZZ)5LcLN-7S;*fysn0DHByDFH^yK z4v0w!*C?a*D?konQf8!Yi%B$!)K!#GR({_@(Cu3>iuz4U_M}@RS(w+krmQZrQ8wxFZtE19zd+3J<;}t5xADW!yiqMtZ4W^;L~e{x1$Yo z8pnr9fFCtD+Nv~LgBPO0>Il{p{3nh<+AK&E5h9&bk3{b|%M`|zEn70eb;)YmZ|9*a z+O7iYr#%TURcicE>a^p6=knNbfx!l~{f_Db_Fiai%?e?Z95WA-!8WQ>ch}m#wKB{K zQJsw`q#A;c_J$D;Jf}?beG0*D<$HwjVe<0qAnEZ~I#n2ibyAyChCF_0KmchNI}uWB zm0eoA2P-b^Mgid%WO0Kd_|aIb;rN=SrVI_~ZFM{>PQ{CUob}PMs%N9je6bj^9K&1T zn?_Go`B%^ey*wf{_9U<@1k170cHviA{j^t#`gU}tK?aM_to8MT-K_H8rjp39?xmbe z^W-^r6WO0vn!uLGRzddjv|2Wm2y3f%_(!s6`RE35;Q zvNvMv%xuH}3C{6&dMpiLUfcFt&>+5uhF#mci9LSOXl90vfHp_4SP|L=T1EctLBoV; zXjZmg_WC`C2V*1kDPe^Cn$}dr*Tz$*VC`^O@=h#*8+t-UwXd47FSA z1``1OVKNX_I;`rEare?AHiDsXD944CQs~&ias1u8wQ)*avyG7bJ=V4g(Z`Zpylw6s zU?hll_{$f#@L_kMilMW(7SAp``|Ko0vry4g8o|-!Q0HIz%IvVcmWobOiEDk%nDqG`|FJcYuvaKGp%DDW1up z)KuV4>}e1Dj)wlpOwo~HC5+4O<8d06riha=dJDhr4WytQU>t(J%kO)cLi8w-GaWUG ze1zgPKchx%UqX~t1dq?Kw9OP4@bCiucv6JN5790LU#tiTV?_Xs##lh3M-`2SUlJCg z(LfGp^r)ioP)@=^G#ZfsjUIxAahiZ*#%U(iLH>pNiY;E#!WK4OtKwAyY&ErbYhBpp zqn!Dt+o136w(er7FIsoC?dVoX+6$~7@UOZJms%L)g*hKJ8Yl-@4`>*TH=kmNhCzF* zg$BRxpmB!5E5sCNGLBij*TBr=k3^kCn^?o44dK-1McXby0vij2jd#%_#@p$1o@9OW zqlS;tM#dUC>0y%e@EV_Cn$|t0Stx1VGd4||PO}>x7fB-Y62v2N5A_n}H%_PZgk^;d zs9Fbge4i*HA0^}#*XW>`=3hr#*4rkBbSjKnAym{30w#u5u&j>MO0$enr4LF?26kPy zAS_sk_x3#qJcj~lncoqlS--S+9MnLW;8(5FP+;L!Fw^4ADS1LhAs$bh)us7Mn8sEg)M@@L zUU_BAtWZXkPB;_WzEj>DN_4y6@g9ePqN6b<}XIV|-)$b-%pd$!n=e5a$k=Rl`pdXMXL z^!NCM!!hv~p#rtp{#vIycK#B;c8>8ox_ezKe=#ATS9yO8F-PGW7-swo;7Qm2AfOq~O)XMw)&lrgaIOG!TO#+hfjB`nw5!g(fKCtKbJNSv>WSoFYta_CZU zkt$&Gb{V~^Ka4tKFoq{*I)20Lx}~53I>A7?;T-Ymo;0%wVy3)OE|kyXypjcn=_avn z9i27aK?a!miBf3OH%T69vnP~%eQ!IdA_V(;kbp{+^>dB*3!6Q*Tah1=Zpcri1o^2P zApg0ruB!YLRwqA|MOA)`AKt$FFF^hx^0WO+Lh@w!$ue-liw&b!gimPU6Y=cKIMhl^ zgcjk&wLxGrLcJd5{s%G$WnbSbQm+mJO1&| zLdROTygV1-`2*mfYAlnqs7DHwBrrSHBOwO7drTOnsqM8JTt`hr{sXWQ@DT}rsTRH- zoT22oE+8NB2W?kOf%SGhy0?MG?;vEkf%tCaP_W&x{st%4QM$p|a1w&qj&|4oM(6t{ z1JSI!7cPb_E97yCJXXpB^^oFL$>TJ7FwZCg{$Zm$6UmMc6+lD<52AtxQNe?#;6YUI zASz&w+w^%t2IuUTo7M!)3WduFwljz$9q={y zN6wT03cvEKyUYr~@X#(cf8?yUid>CI93MW=tWaWiTlsO+onm(`S!fqBo(}R%Y(2RG zk@V6YueT+OSx?a`e$1dG>siQ~v(s>Hd5D->p6>@Um2;4b|I7ruz@(h3bD9z2+({PZO0*ZI@f?hxdFxE;*5f1Ts|Z1i zld{^Zncv2K8BGEi$2r@$8Geo8`N z+D*d8HHeZS8ND#83JIvW9l&WHiADRzjMQRtTWOb+YFwoU~s8s;u0;J4sTg9GkRIw%C%D1TZ}& zAt?k+k8!wU6(oaHEwegaSc?PchM)l=z8kJLecyTn%A1V}%XE;3NL@|R?H5AV5cIY+ zA$D=lU$Bo=tn8rY;O&My=^36{j3@nsZ;ZYAp)YKF*Klq*hC?C=v1KvLY8k>=OCx(3RNFVkmRxgx#;rK%85x8z;F=qq7HLwo!zrQqjx( z>#WC;A(hv3fLSm9LcOyF1fZi1{nXM{Q@j-t6**GWs)4K*U>v_Y`c#>88F52CD#s|X zA@o+eDMzUXAq`@26b%X*5JABK^^X_hi9vCIlSCNa7EX5g=y7{b!o?oQ`9Mz;7P{*u zpa@d&3KT={)iB2AC>r9HQ30gc?|l)+yf~Z>X$W@0E7`7Ja6Oj;rMKwa<`v^!hC>Qw zhK^oTe>QydXXrmP!F&g3_zdGmKQVxtM{|V9z^C8P(co(X^-Ud3S4`p|65b!^A<`NI zBTtflSkP&#aVtXcxJ@3Pm&X_6@kM#uE{`wCfi!+FTSxAq z$I#_eXkRC+wkXF?bwUk4NemgU5mOc%;8EcpO-dM+zQ;$AR^DR03o0IFM|C+E4nKR_?voH_ZIU zS;MXD{{;KTvHu44Ph|g%?C)q|;8Oy0GVo~u`Wg5P1DzW{o#D>{9#s}(7GrqhKx*3) z#29{bhAWdt5uwoA5xy2-`=LHsrNrPlmRdV>Fj||7Y(SS(p$yH(VkIkAFtTh~v0?-0 zG%H*;fx>YL*oG_+iWHmDT{K!yvXgu!N7sIo4*|)H?-sEkoV|&sy>1x`cB=i4qhk{F zKeE#)2*R{Bu!asrYTwDw-64L=Sz^}(G}z9PZj$3afRD*0#@3m{&;p<)J#Xk;c=CpU z+|aw>O^pr0&fT`$&|!%5ZS6_W!Ii@iLMsS5+aR{Y&EZsaeQ*QL#V>iLWvWxe?F&A?_WZepr}(%jG25VV(Jg&|Qp?C3s(V{XG`a(%TFs7&sx zLgvs)Ox@7yQT;AMdME!LWSlU~p+5kS)`1TVU^4m&6^oAG_M$?rtt0pvkk;NQn1fK8 zQvMULaU_6o1gMp~xlQJ?9liBC@}aIyB@DD**;cgl5HOt0;c!@tB~e_ z+>EoX^ACc};=Wd~%^b?Yo9}{?aIJC+o>ut?Fd0$5vz({7xzsOyg>0=-+t|2l>KETZ z+}H@6c^iY}6>2xAyIo*`K!%9mkJ^wzznT9bk|hiKn|bgKPmi{n zrPB#WOB57AtmP%_5_R(lfbG*Dn`x)UDVr#+qRj&~nS<3aF1ze%7?e~kj7 zZ?)8i;Kwq_DBZ3nGI_9tD!_U+*HbSkA$7v9q+qH=zB#lR`1vhxu=zNupi?6_R7h?f z&6fj>MUhqk35#e{$ESg(so)8FWJo``fxE7l2`QG?i?f*>Sm>jMGY<|OD>w20l2N-s z>A;J^Y7g!NdJ>Vv11&kz<763&w<}Ys@H9v0k+ zuouU=7Ir0a1It`%2QsAoVUDfTfyl3;iSO?5^)rFzkU-J9|N`h;N{KU)Q;vx?uT%A#mv&+zyhCx!@+}Q6UP?v7_Z5cd(*d$H z`Zb=@`Dr(s_WG_sdB@8~SLtFNsp-arexK&Mj}?G!v$#I6;N?>+@Cv^k~Y#rPSQ_W2oJWlu|lK zOX+-tN+&I)lj-{;K^cD2jmveMAd~+FI4Ly*84)Sdx1P(d#SJnMb--MGDZgxxMftfw z7D>7MT7njoUq+YTH29?aJot3^WwgCi^JqmLpwS}5MjkFUVkgvgMhY;K&IP%2YtWKz ztFjoh2(RM`!)A~P#z_HQjMNd1xd2zY!MM?3$FkJ5Y_!3Q(>WsrGZSQxYshdg4%v^> zxdxeHb1<&h0Mb&<{dA8~kPBK-)VW$wBOquA+QOpFNl~{4?O{>3SBpA|8f502KtMqrz^>x~c~?V_c&gZ@0w$N7|}k!}=qEKp$olvB9}DR9gX7G>ML z)7%OXDy8evEJKEc<8Zu@;zlR|&e3YbEY8kTFi3Dp&=jAh_#BSdQv^H0r69VF%iPjl zGK<>px63O|Nom@228xM6Q!mk3CtEE9oqnn$0Qk*>GL8pYZ0GGWftc@Lp@giQ8(1Y82i_c&j%(@&}K!Zuyk(P*+rdTdl)1G#D zHdzHvPLDNN^0a#Y5G%Dndk>NJV7a#IjF7*Ob_9b1V-7!{6*Pi&HYH7b5^PXsIFQo) z7uz#qdUo&6QUJ_zm)1ST5jqWZj73kMF*5MJ^$DbeFdUAH1-KDwaJVaF zb^C>1h8av1g`)Ro75asTB_q2BA)I637o@A&72Ib*BaI&y4%#9P{ z_Eou5l_B=dct)p-31-Rk5}tUO@wms2Acm{)uCPmuS{d4sskqs)WBf3kC6>EH^k?%r z)&jCU8PAar*(7en^xPe!2Yv3;vuFLTS!HP@6@xn`iu4 zcX>)tIN5Ddlj1S*5(jwezI+>2YRPXRaEZks#0<3$?}shDi*;$)IHSFdW%sQFRCFZ0 z&@mU|P0(Y=-rEd|7%4auz5`Bt2c;v-Lelkm@%BR?*PHca z%bSjy^E?*Fwc&Sd_Dh{?126QmxXMW*O?z5V{CSuZH9cH+kHHgjaWoJVdEyHatYFXFqs|V$VMC5Y?WU@DSym>4p8B+zP*NfYS9uPcQoX!p40zR#WCum!v^(-_CYM8#u+z zhE7FajNLb&Uu(kFfj7yvIk8tg#x`i1r|4<_^)98rzB+L%K$1yun5JsOvNrpJG)KQ?s zlopEuk~Tc&N*yz{`B8@)*6T4i812xW)!I1GT2zKyMLjV(26?31{eJJTUy>^GR;`y?~tZ3b>)(_JqF+${&kAnkTDvPZI{x z&mj#pr^H7i_?SwznWrwr$B=Xi=SuzjJj7w;3U>QE#hEnEZlTA66|=WNUlQQ(4yA5W`a#Xkpn;<l_46}$wyjOe}crCr1S;&jd3h%VAs5}sMRBq|d zrZYk)g2+1T4fAi27%Tr{$Oj9h^ftHW^d~OJ1(!FYQTY(j_ayWhI%27Gnc*pxt>OQ-M*++xSl-A+-Ut}L;kb*mx=N0 z$Ri+tO8I>}7{}oEYJ?{Hm`#Q86OVy~DZI7Qqgb5&my4%zy}v_8pTlsQ7~BIww5+V! z{u|3IpM@5bE5GKE?38|TTn+7#)zL_|k<;EB^!NNTE5vs(G59hpbLbS<-bE;cACN5e z2wGR{)WPk-eo8 z0ebd%uu{9c64~+@Mj2=Hn-$Vxc{_5N^J|c?>8pLXVqq2Bp(&7(_UzP{kz1ME{6B!t z8zF>ZL!j&@1txXFYmC(BG%gXFk0x+E5x^lXaBY`~0c~8kKEk0Zlj^CYgvu_ImR)`yuv_~vFJ_6W zERnss20Z z27c+_sz`%nyizT%A?XHj(ZBXeMI9ijO#$AlMT@hEsfu0C$z!Jv`UYwW&}N12!j9y2 zVobXv@2y&UCWvQzPe#AVO7`G}wngBfBh{N2+zd8`c;sH+kZF{76*zYWfJAxqTq=u%V z^*LUTbuO{R^|HQU3~a$$7O9LyGt+G^6w10T;zdhD3haAl7Q#eS0mDR;kt7}B`iGY; z(UjQsPnru;k`ls{q=2xV;i{-;Dz`orRjz2NNZrDlgJ?nz`mW26Y8555hUdVH(s6rX z5HAzYcnr#8NFKv@3~|k>Z}&B^PFEbj`9Oov6 zU(Cf#3pediM+b}!kSX0=YZqx=f#!|ZkF;>tk->E9m!uhdK*_;1jXY>{iaw66{1frn znZLDMo13m~>?kB#5C|hX0(cw_7Ws!MP6OI&gjwn*2*F!N%wgceGC4o+d86rOOSkJx zrvYjb^JPBfoCay{4s>otD{~D-cJZi3k-b{<# z{2LTzt^+ng$j!gWA$&BHFZq&FqU`OZg*J(K8dy4py!(U67SI73phIpRqaeKwu@6|8 z%JR7gliTg&(pP0FHQ7$L=m&LBrzic0dU_f}TOF%rLc@_{8wF1ypTizZ*?Vafe=IxuJQbw$`S5J?VUCI4pRPd~YL#^T#&I1e-c zRDLrMNAjT`n@vv~4v6+9lQgtWee9sH9h%sc&MXs4g4}cpZhE}QqQ;pNy4pm4VR94Zo zlQPDBvL@6H8KPGlpa`S{}GsMp)fAr>`dGbPSD_& zFibNmL{yd~#Lw+dgNTKiYnE}JQe;kR@jb)Kpc|=mIiAu=`wy!#^Hibb1~i#U9w4*G zBApVMVdgR2L^Qb)Jwe~BkT&yijv`m0%p6)&Rwui?E{d%Ut(8+@-Ll)m`=*=s>O*VqB1&miofx&q9k38w z1sN42j5MXHjIJYot&Ru=YEjhez2b~WRhi;qs{2dI1iZXuP5G%?ig{S3ptS~Cmq8n- zjwLx|T}JZ4yIm~X>RyYhCO&NDV{l5hNDTQ4X`qv#gy`ajJvrzh=#HZAA(GqF7_SRuSwCEOQutEJ zeEp7A7+y8YT};vrXr18`SQa-O;VETlSE_9YFM#d24GH^y+&~TeO8bMhhks^1fP%25 z^)v8_K?7PNYBrvv2bztiNP_5EuiP^bZ8Iq0=r)6rj}9ZsquUG$tF;*f={AFihHVCC zP~ZMATd=!YTPADHPVL?a7#53EVTmd%P=(T!&xOF@5*pXhRnUY*Wuq@@;cgwr!ht94 z#9_KxrllW`-cwtuwk~XG(MxWdrGt-LV2jE^JR>juVWkfF$EY9YADTk4RvA`ER^{_x zo7KWU9{}5vRbAUf8X7;8F+S64;ud}1gnxryrS>=9PI6?b@zM7Yy6n+NQQ2cqMdr$S zt@5~PbU708=rBo1vN<|$u5!%l?!qGXgH(u~wt-;q>)c~dkZ{aX2H`1k*8s|vS*}pN zsPWNBQ$2*ne^J#X zX8rt=yCI_WYb=h~di@;^gjL2GL8uApd!}ic(onW@KZ*;{fn?RLG}Jv|w!0%Ca@5`% zK+R0{f~xI|mN|0QM^&b0zzJHA|7OwHmR!w;S&_i{x=i?FPxa+Xm}Z6I%0o4&q)*)s z^o~P)mC?8!o71|t%mT0@g#g^}hlFw?Pff@q+oZ*7;{!y4dGZ~7`42UVIs7>jdmN{u zp{E_QDyGA?{8RzdSbQ^8$8gmfYY%p{9^x~56Y{k1i4uQS)G|sh5=w1B8#1RK#zpyl zN+P)rkJbU?r~9|`7-@nYBh5iV3@j+2BNKv7vh&v6>jEFi9it@olsGyP+?J zM<`ID*iPzbP+VPKDD`k`oq$2`Pb{WTn{xXt&Qo8;%OETP$^&M{VnYNe~%5JPqr)vCK+xZ)CgLdWx zdSImTB0pmzzr~aDsErLUtsGU~DD7yOiO}dUB04%uGNAWeVL8*)b<9nLnW-=<6~Zf@ zU(=SfU8^9+@zr|UqU-H}Qg4q3wj;NCbyB^ZYvxbjAaX^Ac{6_^2azj5m=B!9LF7sh znN|aAC{{g`u36-6nH^IYypU@%@itoLmbx+2d3NMw2!r>Zzmv!B{7ly3Tk%GiwpG4~!Z`!0d^7ne z7b+i<-^mlZVDjJKRcOurH|2)8fhS9qLpnB}ofF1vK07BGu=(tqXu#&PbD{y9x1<&IVCrYq8Hy{VbWOZA492Vg9FH`j+<^;AgdTD~IaN^7P+>43u@%W>$ z2z@_x*hjhN&!BVw5(JznK>i$hk{pD8B4`b*hR*SFA&(oCa2~+QpN*$OZ?XgrQ_(uS zIt0YMC9O44S`MAxtEa_R6k2=QC|g1+0`9zB9Xo0A!iP#}X)n7y47# zwB7eNaE8SvzN3fMNsV+2-}Iw<63<4-N7mf;M-W7cF3e9cD^$(q+y)vZHw(a73!FR+ zs`1H>%MqcIMJRPjveE^n&ZRz8;W)EGHMv-b#8b{dgKFu)c{~D5obtRVF;{1wZ-s@Pd_lnh$^SI=)_&B5#)gjOa)-^6d*6BDtpp4he zWZQHj1g^YK;lzhe2S2cyi4TRu$G~H;efV5iv2)5{Ghk!J)+thdo-2;)aP@Vi`r@N}{9QgS zwn^-zw!V}$CvrD#NQu!Ga9!5 ziyBIe1#KI!5fl)S!DCP!L-H6V+SGrO!1%wrK2q+NIEBh{0-fYSMa|~6OoC^JlN6uR^!@r+<1G3lV1;Bs2r)CwRxXA<=GJr z^KAWBdDiHT&NISJHA`!UGeKuRu_4Sqzb4FoK1_}BZx6HYST#0(k=3foQ_XiYJ&W%e z#P}|-!cAd%M2E&lj`5EBO-Dwj?}snbC(wnxUXIPLHkEm=@}3*-ZkD^*yD#)cX*+N9Kx z>X`^P=xwA9b`wI&m%u5+3H%^@Q{B=mYuz+hBYK} z#G7ukb63EJ#}RmRvpn?4t4#Sy3dU(`D#F0UZA#6aWEJ40@rMbSbk!T`elZN7{&0HD zptL#IOpDIy5XZF75NDJzs5}F@wprJ(6|_|T;91z4%J&49nx)_2yXNKQV1Ka9LF`75 zaCjt>a0mYme7^OM2Qe5v`GZqkjf795>dxgVkWM|5nmV{MjC)48e4?S2mPQ6heWVwr z#%W#MgM1flSUN`OpATc7QRqo%fKDH%ANebqXlpU9zRQ0fsGzbsuBljyr9|TWcSB#M zwb;qOAN*s%elZWCN#lci`w-$I;E~1?;fQ1Za8N;8J;=5?f}W1h>-S^=8g*Qa@TnMz z#Ko|1_?3nr4Dlfu zX`&b7|4@o#hVGNH7B{DuJRzaU@VQc?8vtzulx~FQqvUA{8gVX_K+XwIEmtxiWX`mJ zEo<;stBn~nXqDmkXEU}nHZ(VLWJTQ@fQx6Bdm88{VfgMt3%J53cmvCz#0_i%#Ogc7*8G-&T)#u4~H#t9n^9(lh zP=)JCr)HOsC9di^79eduB6(JnIV4J04Asl>gjYku-$-xi>I0v>hU#oeLc71RXvcl_yX7 z?0Y}OMpbcu#~;Fw9%d%kVGZHCn}IvDgJ}fr9NZ3z+E-6$Uxa!5?JUtShSfC<&;C5g z?d1<3t)Non-Y_uq$0hzfC*t~2zBipydHmrl?L7s#vlq9ua~6Hr2?pVA2-6SN6qAStiJ@DB zk;EK~7VwdGDWQ7xU|aHAmnY^jQhL96g@^Q#qvNAXXIYvj3C@f8hqCCEpxEzV9 z=}@TSO}T0W>a|90l@fd1N7*-*Ma2w0e6^Iii zC94sNz@`gEs9Swd4=m&p9`nR01h&dsKn|}1h>P3+>j3gb?kul3h_SYb zUgb`58oQeuj)at9mye|6arC_(X7&CuoY1<$L;F8MWT0fif|8jfJ)GvUoD|BL9Z3*M zcuWf$MbP@QPDgzBg%4Q|qa^quCPJw^#AjA0d8lVg;r$Z-LOg6_V+?_rdmNLUra@wh zwp~D5L{_v#K5$NSvEQtVlS5vCNmp%Q9{8Rmr6L1hX3ZAH8f%kmR*>7Mo_(@#@TG!b zgxyVNziaE};dcmI>b2%c&BD zCKnsbd3@t?8r*&GJHm~&1=s7k7CF0{zmY11HG;SLq#TkxuX!>n6ez0n$ zdBg#~6ffW5q_tT3nIS#&0VG9E$bzm#`*jpX4yaEQ$vayyc)tkS)3lZSFXD;Mg9dYNfv4|OVDFKUn~4!D z%##`P&5mF)Q=g^SzR9D5K^DPiN~&}j`#(7t!@FuQmzBu(Igb3B4NXasG>qJD+MT0GRCykGapdg$)5dLad zI+rgXeHu%|H1pBJ)7~b`+;xad7HY8YVOGfWigca4Ok&`xS~u?HqxwjNM?W)vz0}o- zNW%7R(LFKr-UsWuWJfS0isP!4D0JdP>V632%kp#OFT$Iwt2?gLohNkN8B>QlKnr!a zQ?lba4Ev({4pE0Gv^3tV5Rwc6LyN$rcr=_EI2=38Z*l!{q-@9Y+4qe-|ST z4FWM#!r>&&Ltg2iE!K=yNC%^0VO759rb3z-6?+cFQh3-#kY92!nHs$?C3|F%sDVlp zCZiok`|Qht3xF>Hm?{f0p0r&049Segbwa93sY0iINrDWBoHhikUvZTQ>{Pt;3k!2Z z&g;uW6jxg6=4p)Rb7@&?kD_zz9!2Nas_6IxYMo*@7L`LvcaMtsG%%=XmgJEpTm+C> z@D-9mT6WA9!d9IGq+Je%PJ0Kiv{II6L5uGh&DMb=@K;B(#Rkd(ls`udIry4bodyH6 zKAIz~HAC&zZ7&)?{#DzksYtBj8g-ngdn%@Y)bDnyLzXT)#8A{e zC>~p%H?wC(Pw)OS_T`WmjStlZXnilNtiOz>Hv|5q!-Hp?a|V>A)GM&_@kxXovs5*$ zSE>nNd%gRZ!)gB433z)B@F8pHC^i3(lX2XQJEq0aqNsluz0@31?(f3iQvBrsV6jIX zh;TwdiE_A)C&6gr=nMjX#}VtdoR-3g20g(Fem=uknZnq33fwE%J>QsunA`2o*p7PD ze%|)g_hRJ#s!RS~r#=IBTZY`*#*_O)b|0ERIEPH^o9L^IruL!ftXB zg>A5=PLm1@;-yC&%vACW&1BncQU?P{f_JPHB8O!R z?MrvX06Gm&47nY_qOJ#&!p*uzvb0xm+5e>bI zp$}{5M24=>&>Dtz0HWM41Qb&@1F`^ZM1C>#4IFGH=wl4sgZm0dpSLpRx73dr`Wm1I z)I;h8=K8yU9#-F1e_-fIhJJ`6(vGq#w8s013=qwxvOVG1x~Dy^aY0CgG}11p%Ic_g4IMvJkXq4zSB zHFhv`7DKJZO$?pK=_VRCGjut}br`oWbS*=ZjL$K&gQ2Mg-iqM&$En2i-o_UUtbVA* zy~(nsY3S=!$Wph&d}XVz#TsA(?{R#%%i$X8V0QrSLiZ%Kbi--xd1}dqi{XahTii|X z-{exNd)-Unf7HDk?yuY{;r@?%HQbm-HrLEQ8?Y(4hk>&AA&aj z%0;&Ql$amZqJkE@F%9!^f&jI^uSt-v+Z<^<)q zmEG@h$m3)D|IOiljNq%}gGej*MAJ}h$)ABTh2T5W$v?r(vwKM5K?C>PCC^jGZkUsN z(>Qj+Ja!kbdpNs`**(yt*d^?qz#*rxI|$cO7bmZVbPs@zrGCop3+(=pT{A`DQ7tud zNC&&c6!9jpf-kOw?3W_S?@3W9*C-h3_*6sH2Chn-1TB3bMLN7Ibvf$DL#bQLK>Y}= zqpoi_553yW?B2uflkDzd_Z4=XM#7m0H?)?hB^=rKJJV1DaA&Gjjjx)$YPj(=(^9Vi z-(t(D>2Rub>;|)m+%&tB*)6bp0J}%9dm_85;f864o8}?ah3sAoHw>SLvO9Le0(K8) z_tGW`xsKgi+5Hx~KVtVKc4GnIbg-LecP6_F*gc-zRqUPvH_Yq8U?q6CU6K1uxMBFk z!5Ij-g55bu@^54R4t8&2_e<=4joo|MeVE-R*!?}bb~B}IfE!Y7Yuy$~*HL^IWhPqO<(cE7>y57>Q{-9NEwqzN;Xo@ZIAH9g(7 z)L!gT$y!{;E!C6WU^!}bdLP8To~7DxNaEa>rK}veKD$l155eD>qu8$8c}P1wM>Tp* zZWG)E95TTEmF(u)sK)KxMz+)o*HZJ_2y;1HTix77ZPXXxhpjT^Lv7!W8R|3RNIGgC z40SvF=-86SIF`C&9Od;LcAsSTCAeep4RvCBjl!wyKbKtzKfnD9H1`x@sg3O<%NDqX zy0-la$55YROlqk@I+Awgc%nI%-34%$Y}m~H|7|H`C${4i$<&FP&@!Jtk;?Q6cCTmm ztL#3)?k;x!$!@xXFekG+o880NT?5xppXean?&x?EtL~qJyL7`79P-PK#zsrW9+IHg zKX;64G}LR1>334Oyq+a~#GTXG(->Og!SEluVG+Aa;acjX&R)3hg9}}CQmRjNz6XA3 zhtF?67Jktcm0DPWqH~hhP`~UT{FqluC3JS5%2K4Ow6WLTmo%r1AMCxW`O!}58#lE+ z5DP#}emi52#j==5z0yhWHR|bD2W;!QNdmnZn}*hG!(@T7&PCT}T3#`@91%MjV?HanoIUGB?AJfoPhzry!8oJfVVx&KQ3e!|~J4^7| zWWI);1k|F|Xy{LXvg#%c1@02e10K;(5m2joMIcDK5^tcIx`gI&?pb&zG=rg?ieztB zi*(#$v9&mhkipnNBwC3tV-E|YF7|Fx9cn(t4s^%FN4;BBr@BW&pY^_^CaG0Px3($M4n`Nqj={=tN~NsUizHdd;&0-?h-Wx>&9X3m#W1KN$!`bts0`- zKct=z2r_)vxJ;*i5; zW1E^UaUP}Hrj}LX76IB2iTk9wsv38U`AKz0B<@q{fk@n^)C-Zgo7Ah-xRcDA)D&7= zQad@nThu-bQ7ct2Z&8O;p<~SdRBIxbx2g34DU#tfbz2qlO!Eus;RxpK>WK*E?dsJC z=9g85Ch$7h+wukKRUN8;{Qw^idd8+WVw1oBp- z&NuH?k1=$OIxAHH^s>aMb5k44d(in4FPl^)^+EHSY99@KAQh-@sS_Fc2-00{-m9*c zIB*uIZ&M=tcBZzcwwm{=yEtyAL2cyy$~%_gq}AW4#xu0jBg_ZXjB4EVfEGvM9#pFY zLc6Qmw~veoW;%swfa+en;KM&^7A!soTtlRo?(%enkBvb*K4#wM#<{ z4c{_^9^rZTuK&>Bbc+PxE6=}&uUCLJelM6C4Kadj( z_jN$K)IA!yAL)Lh7M&__KWxldFRI%#^faK~slHVd_Yw7SV~6!8<(e$B;<$ zXLVN zxJ&H7II#+CvC~H1`-J9wnQQH=v2~3=4`yOU&d8rF&{LV~?VPbfLoa4-vD=JCHS}s` zvoYRi9Td#QmOJh7#swOh+;Xoy(U>wMank{H8f!E(ujOHTvhje1j&6Cvo@!h&ESSSB zzppUqd?p^%%En=uSX0jQbe6Mm^s0S9_Mxe;%d#h|mo`Lo)y!YTU%oHL5>5FSfwAPeVrodYADuL)WU| z?7L#`HkvLXDx1{C>{jzIV}6C8Yt_fIN5l>@)-rUBx;cAX>^;V78oC3}B4hk|!n{U3 zl07kYgwfB?M)hPiW*lh@FhuR(d9fpn^;Kv?Y_YMu3VqO|)jIm^OkI@Q5R^q%5 z<(@Z>HeS)t)?B}RwBd~q<|c0k$Boy}t+@{Za|S~@<9Fn)jx9C%HS`^%TWT!U(342F z)L5aR7m#kLv6i7t-rsZQo6C$#bX=@;E1)|x)XdN>4Ry5k+si_(W5w3%Vm0W%)*EBT z7_SJXab)YQvE! z>5)Vy882&yBs$69&n=)&C5cWlGVd2Ho!$1ld9txsAe6%g0bRw=PLH(oUgIW#jE!yI z2Gq2H(*bj(I>p$Bp`9L;%1UFt#Cbn#>$g`L*GZfr*;g8OXozG#)p%4Oy|kUK8!3>q&pbd8!kF6|5(k8CE)Yt)Q!6P)vm672+aYG^z|`)FuyhSo5&leK%fahZll zyPJ(=R|zj>o4E+{(Et(#yw<3p7Nsf5Ny;LnQn4#={z-I(CEc z0z;&UbDbNE3&t%Pq8z?xysRP0;Y&vUbv60EY%FGoa=6sN98(~c;ZEZcjY%}`G;Y%n(fpdx z^zjYBG#=H^58JN;v`a(3Za?4r zmXX;;Ic)O&(Te5+E1|kRad{mShPFn{3$K z0Ksd6cp&(of(Kq49*Cl%fTAd(4=M`!AfgW_Dk=ylDu@TD$osA8ncc~ukG{X>|9hY3 z{|RJkx~r?JyQ{0Kt9yE8xP)EG0hz|K-lcr6#YUwrRd*@4>B4Qlm}9A0tb${9j>)?0 zQp&X$)#V*!j~1i4ysL=&h|Avv)n$(o&oQdY6!D(&LNK;ad0(;IPn6gvN~PEsj$JEO zq&^$|zOpkI+Zw)CX}w%hZc2SEe4jEzi+!HDGyDUkoMYFDpHp{-f2b_dV##Uy!uKn? zG|FCS2f{y6QddYWg=t5_KT#HGv5K_s!ar5YSIM-i)3%0xu5^4*#%@jfIsBl~n`76C z`_n|kA>|P*_GsD}aa8I05K&$$Hl;;Ie67sUV!PAgBED5tXt9GxJE0uZVqc}Tj5w*p zJS_8lhuHT@Z!H#f&KdE8vXoyc*1mxXq6 ztPZgO5sG^15j`z0!mRdNLorGl6%nqAwK7(6&P5RxwW}7Je9q*ED77^m5x^{ZbG!X& z3$;fub}}|r9lZ{+MSM#S1;wX`RM6|N`hL=G3s}U-Nmuj#Kv~!xCHfx zj9H#QlGRf(4du0q z!)sKYCN5t@rrA2jwN%H*n37=|Vs5E!&|7TiFT!xs*2T+dc& zYZ((%&sM6PV}Iwmv{EN>jJTYRZLMC(FoM1SROS^@~eUk8_%o zU|ZF^fl9wt%(mskwN(dlY`(bBb~-jqohD-}-E-6{B_)@Bj(Qiz{w|1TJ9TF;ttc*C zJ#I+rpq6ap5|HoWxK8R)j>&x8Rr-J^N=KSAuBV#EF`1UB-V#hJinFU53~AZwwCD7E zGva!ymggxZ^YvF_w&-c6WAQ>9j>)uvkc1+>PA7O8P!*>36pjYOQwJO#!C^{O#9Tx8 zWtdr;Ql@kY619c1cRPL0COydp9H@tqYw+}HX;4CTU` ze?eoeM_KX*xg>u@RDnhnwSXp;m|4t2I7}?zyfT&KU}C&k!&BQ;#+WqBDyDx5P!%r& zn#2x3v-ptlhZs+H985y(NUf6?8IEU68bjG?*u6t-v=Vna?wTVPZ3wqS)2hc2x zsZ_4ogdVPB=}D<}?nL!BY7ym9xXz7xr#@xFzH2J=_ewdB%aw3&qdJUajN~t+O42ho z(H1FxWBug_lJb#o9Jr~%$vjEBR51r(lUM*~)+9+7RoudOnM+cV9-1_ox2P z=QYwx&W+2J{2SwCDUI=4xh#p_!(pP-wf!?-aBq;|VTMP87*%}5VbTQIBMNH;?jm*$ zVPXy8wg{`DBcMt2WxT}Xb9hn^;wwVIup$UAF($E^@mm?Qtx;I!l2F>2JG)Tcm4J$% z`m5qGgiS(9_3=jde~qcn=V@>-iw%wV81c_=>Zc5k{tw`{$g7H<0Zn+F3$>^r25($! zgdYfuSrq&so@i8!CKSf|JUN#f9cLSa^;AidkU<=h0rgpi!Y0v?F=IHDW*ssbN~` z*9fcPCqP*EZd3}rQ4`PaH3~~RETQauIsXm-rAbIk9_Nx;aT$jtjU11qjG1Aek(Bg6 zs3NFG^ci2~k~+VNQzZ`txUU$@>3!N?D%{sFhjt01Oj-{zO}(-b%@b#+M?<7Ac~D zImqy64vz&?g)uCxgv84*aZ?0gBy37^eoqr*|B~;da9^mJgdgK_r8H!phQg|#R^uxI zfM%`LPcyyrjirTufoUX0+UMWHd<06}o09a>dK>XudJ+wJn<{&!Ch<07luW`CR7E0( zr8L?Z!qNwj_<@W!rb@iD0QsCc9#9q10!Rs8!gwQ%lWE8^*R6-lOZu$h3os-f>5-Cz z!&s^~H`JI`kbi_O>w@X5r?1ZVe)WBXc&IAVp~{1tpm(6FW~U443{y) zNdly-cv>zxL-a>r}vYv*M46!nU2`G6b#T z_lYSTa^m}o{FpD}Ply2>`y`wO<%)zzMV5HDV*urzWcVAy=uR`ki5u}e+U~^!D%}AN znVr5weU5iJguB+ibUKreBSvn6A?yzR&t$JDuXjR$MqM(Gdzj?MM2E;#1xkEKGC|{gs?Tp6+qj4 z?emiMi9X$yB3#g|7~ySU69LC}t4MkZGz*pI04tNSxb&x3&Tnwu0ztdv1%md&3(!Xd zX{WqEeA#V?xj_8Jkm^|=Ox+1X`~3x?W%q?i1)@XuTa$7)Zw~Xx;k-G_Cx-Gh33U=LS#jwtCd#(Gq_xd*ky*M40x z!Oh8Ix%bD4k5hIc{6>%6$uqh1vEopV!^t^EV; z_dJbU7xp}xd>Z(rs-l+k3~xy?Y0)x=?+A?*)OTaW0-3R}MayO?+l$zS?rExHWSR!wIE3u;r)9 z=3W8ysIslsQa}oyR^DRx0bq_e3TVN5W@~W<(uVKQTkt%H37BKT0(e}s0Q_E90Z(!2 zulUZT1?Dal(5$2bS`^9~qjW}it3r9VDU^4+LV0&8#B&$Z>`}U#EMl)>2i&jp0X(1# z06fCEj&ZKzoa+>0eq{{4B?3NX>^!0@mAJ*IREKz#>X4*T9a^hYhg6m7U{mwJv!hx7 z*i{`3*h4J_w5t;Vd#jfL_EV`QL-6`&i^x-{wj;QdF{&H*5_KlvL{7bwQzvt3IoDwt z*TKytR&$AduFo8<$(3A6K%E5+^YN+{i&(^bZec!4na^EJf3JF-DORjdZvuQ!{TA>M z^?SgzrYFK<#a`14Jc+U2bO7*xX^JIQ95hu$#^PC=sHj+R%(MdVxTzaXB!6#u0`Qb+ zdQ7bN)ie_4{)PDzo&Gn^i-mm5B#j|vZmF4DYHp!s;_0$wtujTl2mmIEC4k)-lgsdY zh8Hp{W_Sr;ndPMUaXj`Dj%~qlm@|jqS}eN74~QQgKPrA){Dk;R#urHO|`J+Si(E9dGqpudyz%K4yK|y50Jgb+`4O)}z)_){MlViA9N*B$g%m6JJT( znfPAf!Ne1ZKPN^cr6zSv%1RoLbYW6a(&Qw6(p5?GlkP}*E$OSI7Riap9g@2z4@@pd zE=nGsd`Yq+d1~^EWMA^t$+sszll*e>>&gF2{wz7Q<%pJZTVB`l;g-*~e6i(@mOWbK zw;J7Qa;rqNH3_~zGCZZ0@B>;w0^PTX2>&NdRGCkiKQqj9b_2B&FTU>wEb_!LINRC}Pw2to<3nx*IQKeI48)Uk zgYZ4eq4D~JCeZ0c1dwU zWZSv{N(_ZnJR6Cf0q9H^U@`Plh3-TGPJnKz(3=*3mq0I7yiXg?$q5H^QpHo0$$%Bm zY89_QP63<&tyYB>+Nz2gXtauBOzD7gq0K6ua_j_n7tVhxVi}-{SEytld=H>1?u8wp zTZ#mi;~cmu?gzwE0iqYeD;TcANKnKBfU0;9V*pQUFkFohq2fu#KEOPJQK5=87!!DU z0Z_$v6VC_SgHfT1_i+AO74PE-Rs~NY<{-QmqeK<^Fh*3IJRA=Ehk&ZskMX49iNp&5 zKgN@*s`vzQQZdVo1w0BlDdI~&>?uN8*h_}ARLpym08c<#@Ya>f03(!AK#Sr4j8w`1 zqZB8g6=$=tYEfK(Ny-esWTg_YmEr+xt;_^WQG9@HaQ<2qZI#)8shAH{k)~V$*h#qx zu(NUvU>BUA##@J!YXLKq>j1kcHvncS3jnim`dJm{DmMf6R~7>fP;LbrqAUR%hEvU| z7_Quj7L5SJzM8TO;gNu&0ExBbNx&b$dBI>240t>Icu%!w%AQR@{Mfi8&a9DE=wX zCwUbjgpXzA}&3?V2KrYkhuar6`&*-C5=rL{#B*R2Ee`y$-(%Zv`La zD)V}Lo~iy!Baa~A7>Czc=a;+u z#bsVswZEWhsz;3RI;Xnk9&n{9dOM zkBV#6&-GN-1|#E~m7ZD7dU+(OQ8tOr@#Ad=Q)>K1eq5z`EYJoQ3n)llP~~@eXF1#= zzpAEEgqju-P6%g6&abTY*BauZsE-VBw9gQeRWu+p>4aFLI7rq&!3-N=!L|`jGH(Js z)rnp%a~hZiyHJd9_@?E!D?DD8e;V{iSDZYjk2@9}UmrILozVc*u&e85sHYXs;AtV& z&_18j8`N&6cPjL?%2nxbmp~u#Tt2@8)u!4(8)QT$E~=*9^Xbu03p6zk)#8}gsQ7!M>rkjMoK*_hZZZH#xKuPR#S=L zrc>m*oyKTT6N|h-iRz@mG#$~1B7dBo1eNmUIs6ViKBhnq6;Jazs%99gL^X4kxgDCd zXi!mIQlulqgY8c+knip}^-P=Z83#Hbp#-xZ9JICH1fRL#)y=X%_3STOF> z0vdsu)iDH%@eUI=8v@ELxVwVo)a!4qXG7D*$YQ5IIPw|6riMehVbUXL%`mT{f_sQ@ z+SrxZq>mr?en0*zrO0#2j*__&jddI5rMJ8p%DV8hJ3sRnp3pPIY-n;x0GL zhA4GALXmyR0rNRvOV4E7{gJ^z_r7?;4mClj#rYMDAHFM?@pb8lSLH3OF+wYj-b{3Gh9PVP* zT&F1XRItugyIp8|=@cnEZ@JT3?5e18O?8zyFqB!8L6M-tgS6tHt4|Yqi;2;Jag;5q9DYBHJYFDU^ zJg@6b3Nny{I(nGL8`RT~97w-3Q8Z1Ur^0gi$o~;K*gM)`UlP$A8?tpWbQxYiY5*kZFRzMCO zStGKL#`u(CkJk^staQp~r?Wh$I6gsmfoWy5bM`Q@v7BAT3&BHj3yong(5#nMsBBcI zP-EN?a%CawpsG>hwA_S~QsWTZ*BWPOsTd9KT*z*v@uZC=L+@Z9z{{jG8PX_ZL}p~! zg>*~6?vw_{564Dh+M{8V>-PAZ<#Hhqat#G1OUW90&M0fmP`RB|75-^juS=hNKLeiZnr)cYpggb`HX|V8Z`10A%3LLFuMg+&>&ZN{v6CyJ|C?g zi>gL@SRXKBu##q$u}4$t_BhH*T*$?;*TBGKz4^i~?`38mM%zNlJ`so;2GnX>?i2q$KfX-`&tB0^<1Mx9$9 zMXYkFSo<2}H>5ORV@T1tq48RM#%TdWy^b;rI9>$FM6IFvI!7Y&O7g^bxK8krVc8{) z>drnP`RvA}k-m820k2PHM9q5*qJ(T=ZeC7F4k-vP8uT34Q1H9_wIO3PM(R686g+Cb zw}zKJ!r)aJ`jJ{Jd(^Oan}iM=jWw~S%70;%XEyEfz;UmsWM#uFKDNeHHp52~(#3>oBbl6mpgIQ&81HpyJ2=$zDqp>X(kYEpF^JNYQAeOh^q`?3Ix5K47o-X* zrB0)(r5-26EOi7oDKwWD^3^AC4o=lpYhXM_`u$^QM}e$Dqsn8M)fj1@)Z1jB(@`NR zG&GcsNGQe7?hu6m8KN|ZBSdLHhA4wl3eg2oAu3&TAtD_Uq9JjH()F0Wqe66{?G&O5 z#mM$y$B-0+W)7^2$YanI-N!L~(JZ&~#KmMjifO)eg!rK1y3wa4NGQrv44caWef|h; z^TD!Ga*2l~;}Tk~i4i5z&~i2c1y!L$3>cT(?Fg=&$2qIr*pif#un?H-CSc#oFtkRL zkj;l(l8m`3`qZbFmV-?x9~=N*u>6q!?$ewt1BQHXL#;3@seIqi+Tbi)?DotiKa%l+ zNAK@N$2qa;k^N!)~~pQ~i~gObeZkshZZ{g{#` zBWjoIJfChJvA=|UV*(+D9Hq)@TWykoz8$Bz8phq>BHE5(Dl|=SOmj_Oiz&@8xtZ7UHXT|a3|0VQE6On(hkS@*AqDaWKf z@yM5&#vQ`@d@@u?ixdoAeZ_%C`ot58>fU6(O6e)yatC&{d~WJ=B}p} z1uH@ky=c~JU8i}oAgF;P8OqEGMRdVI7Gw$6k(rI-3sui>ONLVPGNn?=JrJ6|q&~VD zE)um{G6h8fqu1%Eq$=n&%>}~ml=m$RVXO**4c9gSKx4R7hiP6{KrR*YE8VWCs-PaA z)wy24C>J&kFgUzrsCBRdutH(9HqVFfT44>zHFP6#Ne5vi9FpH|#r{fyJ z0Ba%)lJP`U<#6*Is|I-rs`zfwACd4BChvA>J}68)t)+0Gdswh~v|T9gXBE)xcp6f2 zLK^P$8*X7q924?A203*xIp^az*N5g1*mR9)y_j@jxClwZ>s8)u%heFHf9iLNp-$TA z;Qpe09Ly^`g-Nxcn^xE^!+t*8KEs@9oO|Sq$0R}ZC}q)09>E~CqS)YMVwJ1i#}hd| zA8wesYvC*nbGe}{L`50jkS#tFH&jacJtf?0_db8n@?JEMs_*mm){ zDyHEkm%d!rtAM3=Io98e6UZnys%o1`sG91ksF62J8z+fZH!#Tm*g$NOe;M;dBbJ8>pXaZ-iTh7vaX9sICd5Z>HUz)q_(oZ(XTZg(3v{daP z&oRhNDN#kb;;AkzsB+G%!L}4mI5?0^VCNhvgS%LOo@(Kf2RGQ2h6`3ET}#}U_4;*_ zWkBf`Vm!uL-`+AIzp7kEbL9{Z<_zuQigL}!h=M#9@0K{cwT5A(tqY`K9O@y*M-CFX zLu|zG_I=PzMHBP&2Flzl+Ta#_quUTzCdg%vT5 zYu=0AG%UO@+=Z-#E)!XQJtosMLYbsRh=~@24V*^zE`=oE_GlTkg%YExa2G=tgKQC_ z^-&DthCS3wwu+wWVyu*1So6|+g3(gwsP)ts#*B<#=)xUWcz}H4g^UZn9ZTnd>Pdw( zC@2V68vnW3x`xmvN@O^fH}2#uWo<8wBTes{>33$xy<#Kk^OhM}O+!=w#aGR!$_C3W z)KDdcdkNg@Muc{M0-bNfN~szZP2;HFi3llhXz!1DD(KaTayq8r!qLNNnB{pID3rHC z*t%mM(+7#ljY&(AR1mGe<>WhAOu*O(eMC}_k&XD~QJ5YMM< zsMmO5HOf&8rPI@9_vfR`7YE(KT*& z{+u!=bAyA9yK$Nw(KhKcc3KQwPLoC`hI^?V_bf~tG=z{Ej8h-WjW%F|!*-OT%25Go z4HqQf9`*9Z0tP=)i|P0u?xDDyup8uuQV>TPB`&9oZu($ze3r}Wsp1`T()to?T}wAf zt2L|XFn0|GNI7%&^k0s=u{BPt>GG>)@-+{07saVY4i_vF4KhCFA*WMm z1(-ces)i`fwsNQklMPYWwOKAtjZfF}Dm00lHa-bPkrL@E%VJ>Xb!t8#BzOil3=`=} z(ssSnGcH{=h)89K*k48b{-Zd#Y%v~-znRmiflkH`{3chl~0(2duQqlT(E zMc#PRPQcMZw!}lWBWQH6kBa>f(ue|IJz7Eql?#R_l!NPn(I{I28r_xP$(dP^CxnH7 zwyKqOFwes`PDo=zy!6%xr&dKEC>6UeKE`D+%oa}E{c_@VSG6k(zii>p68>!A%M!k9 z5!xCl@r=j08SVHNJ4m6TSiEq2LYS(0t^y*uv!vZeVm;tS1sD82eZ3E#j27(76zylK zskk$O>Ow78prPG3YBQ-u=yn+pO;58VJ~;*`Q+|V6T9^VrpjjOhE8rmDUa&UqDX-oa zx-&x)ArZ<&sGh3ZI(dIW-};jdEo&D>cbSKdFL6tP5mX8K?!tVEB+ar>spG3$Aa}Ad zv0@IV^_a$iZX9dn>$Q@*{<0*>Uo;z=t$O9SNLV@eY0QfV45OQl|Dhl{^_7Do+PY(> zv&KYRHcjT1YE7-9F-5EXP~Q_%P2&Y_{rO;OMQGSS%=ms4-7EGB7oYmVPNoBEA~}vj zY{*{lLQ;1S^kKn+L?D0JG;TyNg#8>h9UEcDNsTrZWM72}q4`3Z8OWcTA}J`y9DrtL zu2>%J)P!9RMI@S&Co|WNHLZ-2vY`@6EEpR1Pvq{YTnRT&HXa)!D7Yw<)!O|RO^2!a zKD{^f6%)6K`W0gaXWTieb+{k2d~ZqW4oQZ+Sn5s=5GJU36oD1Mi7ys8MR}i_WhniC z;QkJt12EyalITi2#o~wAo`%PUh6s91#Faus&%qbB-0(VlLYzMh>F~PoWK}QxpUwX> z0nf!#1|B@+QUPo>o;jfZy+kM{9>5NpgQsIeoWzyGCB>3c2xoncJ}%vf5*;Wn6IT~7 zUhsz34|+dv82P~K-2I4oP(NR=dV|!LFfHCvw9Ep*2-V6%n<-AQs_3+t9j5Kc4-p22Mm)AqUYD zB`8{8O^eu6aGirxD#1lL5~|^vPeJ{uodt~Xfrk&JkQ5jb=VKZ_a{$K{#HkYHQ>#P^ z>MsZC1^dh8dcXytWP&75FL+aXsDDIcFkiY}LmyHdpmPcvpn+F3$+aBM&Y}L%@H)}Y z9BylDOM^U#GS3)eYZGPOdN>obtEK?8o`tfh_2npiB6^|_SH0gVz=fok30xO(1$yi% zTy3EC0aBYOT%QNE#gA4Hm&WbS6iT4(uM|5PVzZ$LDO4LOqYn{cZsVdzaDQB^vHGY2 z)Xsx0CDntYiYB;m6|IcIFAw2UjMU>mNyVt(1t^yC+huV{eUcyi_+3^$aPWZe75^GyuOL$Q!b;z(mLx9#n*tvE!LQk!VyNY3D>j z!|^3jNFB+p6D-D0%AgW2&5UkXoj)3+`6!mmUl~}Cz$zdJGW!Dnsekl>NqBMy+fWo4 za1xml6lB<>k+s3xxPYgj+?1&rkH^>wkk$nh#!2b_n<=CVjF1wz=dTE36sqsTe_aqw z%{3$lsyx}~DJ*@`OVYWJX=z%3^@RnE2rT$3mD7j7pRW{648L!7r5Ue5-%(X=|0`8# zD5v_f@4r(**Z!4i=@R-g)%h#3*{n1Ey@909Z#3>{SU51GsxdUkLvXOKKsrM6xzrIk z8%~7nkaK5!n|8iIlbY`AP}fO|C?__(^w5Ndj!lqWNi~L^9JFF4iIlL|xkv5XC@mjh z8q{8%x8KCrkcQmC=kz&89v;PbK8JZp-DuE1!4 zz1Ea4O&|aSGHjBU028OE;TALAm4Y{M0I1RG?8;OdePSMuXV8}*-+{O~7 zW>7_ORkeT`jof)szI$;&t@fJ3QAi8fZdrk7Nx&Vmm)jTEYt4g*M^GOKGiiqzuTT(X z6M--S^g0uB1OfOUg5_EWSs@DqRtTAp^vzuf(G>^_%7bvNg(POWQXg3?s0kA*oPw?@ zv=*YR(Pk`CA$mn&UscBw-^kgg}4*5+20o&Jl_xK+pA?TM&pPfY(qk$y%aYXa4Q%*|TQ+ z&YI!D3bRv7-GGV;QU1T-`Iy=Ns9(}wS@@G8?j*33)Cod?XjSS%H4J(Ycu-<-F`);b zpk}&QQ=%bG^oX?+{-DOHwUf0|Bn?+wttpH_w=xD-HYuEoOwG=CvIQ-q(sMZ8!um^S z1XL>pctG)BLj-@ZHj_1QOojoGox-5piYvaCrO>F;e+j}Ij1w9D@Ih=nmBv5*@Eu`= zizjuVp-)KYhYJ111+s{Rf~wYZSe6y&QJ57ZnxJ=T7=}n-1;YnPcrSnf4Pk`jsC3ygrj6@X~0Qni6sMOiN(m^Q77{q=u1Zn|G#!jFE)!Bf8zmUM|#00Eo6SAUg;R;*{{DW@{E(yFMO-J0C9#|ndVgV2k zVky=D_==IB__*SnEMcaFx*{Up`FX;&C-xnGAanksaZj9SarDTU>Bkn|@QZ1d``W@~ zx1IC!`G@b`_ul@OKe~H&-^6tFmT2$5(}CNs+4kw|_{Fb9%r43}k{x^7mtn^a9!cN& z(6>iUlwVpHv*hK+mUX>sN{>gKJ<@)De~|w&PtQXquD<-qxNUa~>YRF$HP_kNR=IUa z?@<@;UP3Z)VRZy(Vi+44ftO@jUGNMcK(rz}g0=?sB7#_01l-8IWDcfSg)OG&f*R6sm+}KOFO8Es%yFQYpsuvSMLKtm4f=Y0;urM50y>FYvXh z!du6mUU6Fcaugso0@*DPp)3*N)M_0Q5vGM`jR^h&ArQ2dg0%O6rA1wGLD02)567+Q90t~ny1GuDP2&tAd z6D_o3AwB^|9(_Q&G^)h}abmqdqiRGXMx`~dEFo|o+Ksh-aHWos7LQdsHf_*3*l$RV zh$A^#-PUTlvUp{`xJhEw1g4>aw9SD3erqA|FGQcyYE$JA9azIcdPqh#%8inZ*1%I( zjJ!xLJFc%L1m0lpy-z}xHSk)J(jrNjDaQ*I zDu@EH)MYX&mcYlTgJ>;G?6I{0q8AWiETa(N*2x?p7#(4zr8Vcm03e}*0k;N$$cQkk zzbsgng$ol#cr28Ne%L`2X(rkNLa$S&(S>^7WRl|klv(Vv20oG|WE(ET8R`bno)wXdDnqtt27b^CS^#GNM>*5w zYFM)2g>iy~#8Wqf21IO|h*->@pz3c;kRdfTAq#sf>9IW5q_T$8#Y8H?%twd?$+<2y z0=fv+v_)ve%dXL8>c@0yRN!mcU7!ng4LFW4loA!^EeUH~0_{v#>yqUqB^FD4Yv2c& z7&t9+p8+xU1|fL_V&h=~(n+jm2%s}43(Dh?GpKBuP|}T+u(X32hFlh)bRwloz}TNw zMYPDwycB;pg`4Ta3+}Mr%T__a~6?yaA?ol|-DqjKW zbn@#!iQ;T0@Ja~LHiw!e&@6#w2{cQfSpv-xXqG^;1ezt#EP-YTG)v$=Ljw3dAS%*Y zh(P`N@M;k^#T(;^ZUlZ4CoAFJT|7_3l?-NVO2`29RFO9qrPVvq&dcVGhBUf^U4?UT z`tf!u+lF5crqPe_(-CyzQy1D3CmL;U5s9*N+KWJIcq#=n^0|~ue8DIa&(ZV)M&M9; z0`fGxOvxh+!t~8Rr|Ig$_^_%}SOQ2Z-%@SyqK(hpz zCD1H^W(hP)pjiUV68O)Qz!(MJ%@tyD_J3yenrqc8fo2IbOQ2Z-%@SyqK(hpzCD1H^ zW(hP)pjiUV5@?pd|6Bt0HsGPE!alD}`|!wa*N?dVrxr?tx?*0NM4;kSMahb_$AnvC ziW(Ls>=ofr-NO~LGVeT9F|U|ppI|@NfQhqrGAUw(ZPht}R56hM7vT;ny;Y3fGeZyI zT|ocsw)$+%@sF=PbA6jnKRF${BP;#>``24n%u9N~K2N1zCpCU#%I~;5NwX>&%o5q`?5?j*8!000mwi0iR&u<&;^w0KqXJoaqClf(* zVysTk!&XpLmYLPV-c2TS&=YL*y-pk6hlv+;S5?@w7j@g{4VYQI?b(vL`{*KDVL{H& zg2IB5Nw%Ea-25>m`FTBTUCT21pJ&rq$ujKcv})1+JbRz4Y*~b2nYQE8uI$k>vo7_i@TXTtKbz2E!Ux5B zYd(MD+-^_r`7!d6-Y1XV@>^ugt`FN@{M=iIf4uRj`?lWD>8qW z%y?|#<#(9R^qi6~u`cz^nM>bmKe5+)JCnlZ_kDipqZ>wzJo?S~?H|8r+12Uyy070l za`>IoH$2?;yl3?QawP9y z^ql)2y!zzo2=6(cP5O4{{LdFGE&On_#6`_DdKF?7Vkx5OWO$#Lr5;zLW` z@eMw8=Dwo&YsbHHCZVj%KF_S$=b2`#FsX{F##`oAUh0{$r0Dr=XL3JHYJFdW8vp0( z0F)Ryo1NXSz7qEhD)9<^kVQ2bWZLkI{@vkuzP-O3SJ@>_Z>7)XnQE)?Ic*NVZJOU- z?Hkam*X-G|GiPCJ`!KdM%RH66ywwgGZT76JF7{58*_3#WKJJSa{2z&0TJrpVa@W>)y_|Eqv;T2Tesc zA1PXW{K?DT>6P;OttU3#f5oloZy!DT`RL=nK6(4ZO=Ug5_}h;et>3Et+nB$9eaGe@ zA8zS%Wa#+!f4uIy@WTt2rDmNp#qBA)w_~^cZQCxMcXHjgt4DpFwEDo}_g|m(ieus$ z@19fk5k>oYdCF}27Q8v{idQatq3f%4(++~pUkq9^dCO4c(V|B$d1P?= ztmW3^)4rAG%v)&g{^c;WuyS#`F`2ht*lkYueE*#A3Da3TOae)`WGs$d!@tIi-)!NN1IVwPF^|JX3uUtZQ*U3vzHxTvg!Qf@Ge(e zpoWVF({G!f81?F1hlWgeHLTN-C!b81zUI*RJC1hvacRb7L&l$csQA9^eFyY+T713- zvv)ta_NCXu2A<77_V*(nbbROSvL_-}|MFSe&(GvUO}_(Hz=~PyXK4lE#LHsgz=1a= zymP^iWyd}l(xAfj>a6be3^WMyRD1e5Gk+$CwA_}}AJfVxSDDx2^Gx;I@ZeQ-X4X0O zR7sp%KgATj2-ueE*mrSbXe7X)4!aI9qM=qJvs zo?Gc3{bcK%cSLqg7ZYxo>^g7rh1Q6H7oEN2mj|atSsvb9chQ7zpE>{XmUXkuAN;uG ziNNi@t$XX5_gA;^UOMp27miyVXm4L1e%%}EZL<@v`$QY0kJ#%Tve&I5?N`iociZdk z48&iutNL4)_x=uJuTFY;)ZfnTSn2)W@4tEfLdRio6>pyp%fBwa5`j)tU>sUGXjh&Bv z9CqbLSvL<_9$!6u^KaIo)~>C;?#lf<;bL3Sms75I^3jy--OuaPbBlAO^`=g7We@yR zl6pG*jrWsJj$2!mn;mgxUaM1wD%>r`{`lgFaj(C4c$@uKTUO+aX}4#z8TDS8`p}8M z0n>&{zJKbY?GwIn7Q8;L1H7d2mlxL$>EqeF8lEK5?N*(`j^@r90 zH!P`HzIyixScNy>8$6}?2GgUL6>SwCKbo*-?~uD6+49AIgjuk|4!|t%bWa{@pR6o6 zurg||dpIka4ZJx#Q5|2Lm1s{OOJhllnt%^+z-{(>sjo<- z@plZ??^!=`oEurc4)%0u-P(k#TQ1&{Z{tsw!*d^#n}ey{W|XF!@>|f9Z{aC_)%@h* zz0vmA-nX9}(Ds#+y{@P{ufwR5yB8fg^W>RV)!ywozJ6%s{*q%?tN!7SeV9G5WzyJ; zekZPedc&dt!#DOHT~+c*R?L9PU*39a$C!KDKCyc5zLA{=Z+vyf;yXSo_^xvA(K{~q zIP4$CA0B_+tn)Sx_=EuJyAQ?pw0Ve(~^{@(u59{^*&qZr|8=bK6+`uO-29$g9Uhn^&u>HiPfFWz){XgUtTi)Wtvb|6={x5p!pBi=Co4`p>F5 zbHQB^7bcxhhMh?k2Zn!8bTI5-pp&YY9+;>?aoO`y%Dl2^-qHxZ$}{b!Gna z{*z8W*X7=xqwfE8)xmx@^(${b^pod$b^FJ&?}xwnRkxQ8w7Kre564;tec%4wJzFbp ztV_--Ex)#W+nS|4Zu;<+^G3!!dt{Ge@vK>&?(1~6%|kaV zN?mkeZRy5>pD)jL4QN;Lc+IF!$`9KIepp_R_scKaQism`V#T2RZ)S+)Ylpu0e8T#R z4*v4qs%~|A+l^i|eoL3d)eo<7w>?{O)4UhzE_`_9Q&Z=zX|;Ms_}1ZHJ-q&CR&w#6 zZswQH`bO+u*d_PZvLoMgyy229ecw5f^+Wc)%Ri}|`@DUv>-v$uEJ}E(?ad{V?DN9n zV9b7!#w^Mak%0G<<6m#1uxR(-zs6|LQYYKqC%cc`-ltFReq{a5h4Jfy^$$hubu0h3 ztzUK{>!=bE?%IqK1v}de|7QFvmJ6)5Q{%t;ru5wdZ{G2O{o~&zZts%4>$;L7$8U|_ ze6stNltZR_qOVUoxvu}BO=qIh2KqX$ozVTwj8)0E%uD`k_5(x4nHJvnO7-*Yj`sfX zWS`qckH7ZR2li)dA5RG1c=6Eik0%I&DIk_wTL=8*=}VJ;1)d?a}vg zJ9n%7?e-7bS9E-%*RI~5fAP!Mg6lU8+|{Y{{bTo=95<|)HstkFpP9b+N0@Y@<|#uU zsewFErNz-WmkWs|mKr95O_{O%wXwG28+yIF;+ZF|xxDk!n{F7FVXs?5#-f9{ZY37; zfhO(FO8Fq(?34HDKe{tKXh^!?X^cu0PoNs!hX{hq`Z@xZ~*s?$R^w_Sojx)ZytCX9s?l zknjI4GJILkKRPVfE z^uF*-Rf}SNn{v+3(@U;g^;p#XyE?=_G3tsgw|Y8nnfCL;gO_*sYWsbgZ^)Ww{s(-# z9oR#qwe)|B;Zu#qyWY<4in@Dg&eS%EBTZQ`hJ9Z%mZ712;b`794#ktP2n}X5XIahh z54V5jx=(t|RVR+T_M2tC8@FJuAw(WSyQC|ufp|O%B;Qi6Jq@(7O`x@=q_h`QPf3kB z2p7*hPZ6H4N2P3A@cgVC8q-2PS3 zgf+|W*|u$U#oI+~-k)^z`2FT${Y%Q&t1Ikpcbqiq21~8-{ZH!_=N0q^?8CF>sr`ZK!&= z@!Iu~)^@K9xc{3b^l9^R+bga)epYkXEd!o|tg_pI_(pJaz7S;ZOT&pN!eO{Ef*k9XUMn z0#DVT$iT987jZ+kO+6 xG(7w6&-358?8(D-?0IivT;{K<%61;U^3X5VJwJ5W|A}()y%x0(-HVTV{U2iE@k;;z literal 0 HcmV?d00001 From d691777a88e9c173035c7e2cbe11a939a797ab34 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 17 Jun 2014 11:35:32 -0700 Subject: [PATCH 034/116] Some quick changes after call with Daniel. --- .../Controllers/AdminController.cs | 29 ++++++++------- .../Drivers/AuditTrailPartDriver.cs | 2 +- .../Drivers/AuditTrailSettingsPartDriver.cs | 5 +-- .../Helpers/EventNameHelper.cs | 2 +- .../Orchard.AuditTrail.csproj | 2 +- .../Providers/Content/GlobalContentHandler.cs | 14 ++++---- .../ContentDefinitionEventHandler.cs | 28 +++++++-------- .../GlobalContentDefinitionEditorEvents.cs | 4 +-- .../Providers/Role/RoleEventHandler.cs | 35 +++++++------------ .../Providers/User/UserEventHandler.cs | 4 +-- .../Services/AuditTrailEventDisplayBuilder.cs | 2 +- .../Services/AuditTrailManager.cs | 26 +++++++------- .../AuditTrailTrimmingBackgroundTask.cs | 2 +- .../Services/EventDataSerializer.cs | 4 +-- .../Services/IAuditTrailManager.cs | 8 ++--- .../Models/AuditTrailCategoryDescriptor.cs | 0 16 files changed, 81 insertions(+), 86 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailCategoryDescriptor.cs (100%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 95c9496a7..3b147b4ba 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -28,6 +28,7 @@ namespace Orchard.AuditTrail.Controllers { public dynamic New { get; private set; } public ActionResult Index(PagerParameters pagerParameters, AuditTrailFilterViewModel filterParameters) { + if(!_authorizer.Authorize(Permissions.ViewAuditTrail)) return new HttpUnauthorizedResult(); @@ -40,19 +41,21 @@ namespace Orchard.AuditTrail.Controllers { To = _dateServices.ConvertFromLocalString(filterParameters.To.Date, filterParameters.To.Time), }, filterParameters.OrderBy); var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var eventDescriptorsQuery = from c in _auditTrailManager.Describe() - from e in c.Events - select e; + var eventDescriptorsQuery = + from c in _auditTrailManager.DescribeCategories() + from e in c.Events + select e; var eventDescriptors = eventDescriptorsQuery.ToDictionary(x => x.Event); - var recordViewModelsQuery = from record in pageOfData - let descriptor = eventDescriptors.ContainsKey(record.Event) ? eventDescriptors[record.Event] : default(AuditTrailEventDescriptor) - where descriptor != null - select new AuditTrailEventSummaryViewModel { - Record = record, - EventDescriptor = descriptor, - CategoryDescriptor = descriptor.CategoryDescriptor, - SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") - }; + var recordViewModelsQuery = + from record in pageOfData + let descriptor = eventDescriptors.ContainsKey(record.Event) ? eventDescriptors[record.Event] : default(AuditTrailEventDescriptor) + where descriptor != null + select new AuditTrailEventSummaryViewModel { + Record = record, + EventDescriptor = descriptor, + CategoryDescriptor = descriptor.CategoryDescriptor, + SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") + }; var viewModel = new AuditTrailViewModel { Records = recordViewModelsQuery.ToArray(), @@ -68,7 +71,7 @@ namespace Orchard.AuditTrail.Controllers { return new HttpUnauthorizedResult(); var record = _auditTrailManager.GetRecord(id); - var descriptor = _auditTrailManager.Describe(record.Event); + var descriptor = _auditTrailManager.DescribeEvent(record.Event); var detailsShape = _displayBuilder.BuildDisplay(record, "Detail"); var viewModel = new AuditTrailDetailsViewModel { Record = record, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 206e6bcdd..5014fb060 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -50,7 +50,7 @@ namespace Orchard.AuditTrail.Drivers { FilterValue = part.Id.ToString(CultureInfo.InvariantCulture) }); var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var eventDescriptors = from c in _auditTrailManager.Describe() + var eventDescriptors = from c in _auditTrailManager.DescribeCategories() from e in c.Events select e; var recordViewModels = from record in pageOfData diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index 5a49b941f..1041a131a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -25,14 +25,15 @@ namespace Orchard.AuditTrail.Drivers { return null; return ContentShape("Parts_AuditTrailSettings_Edit", () => { - var descriptors = _auditTrailManager.Describe(); + var descriptors = _auditTrailManager.DescribeCategories(); var eventSettings = part.EventSettings.ToList(); var viewModel = new AuditTrailSettingsViewModel { Categories = (from categoryDescriptor in descriptors select new AuditTrailCategorySettingsViewModel { Category = categoryDescriptor.Category, Name = categoryDescriptor.Name, - Events = (from eventDescriptor in categoryDescriptor.Events + Events = + (from eventDescriptor in categoryDescriptor.Events let eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventDescriptor.Event) select new AuditTrailEventSettingsViewModel { Event = eventDescriptor.Event, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs index a3199546e..64702e7ad 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs @@ -8,7 +8,7 @@ namespace Orchard.AuditTrail.Helpers { } public static string GetFullyQualifiedEventName(Type providerType, string eventName) { - return String.Concat(providerType.FullName, ".", eventName); + return String.Format("{0}.{1}", providerType.FullName, eventName); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 85063aaae..7c8d43ca5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -191,7 +191,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index cd0ae04f4..d795f51bc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -18,27 +18,27 @@ namespace Orchard.AuditTrail.Providers.Content { } protected override void Created(CreateContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Created, context.ContentItem); + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Created, context.ContentItem); } protected override void Updated(UpdateContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Saved, context.ContentItem); + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Saved, context.ContentItem); } protected override void Published(PublishContentContext context) { var previousVersion = context.PreviousItemVersionRecord; - RecordAuditTrail(ContentAuditTrailEventProvider.Published, context.ContentItem, previousVersion); + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Published, context.ContentItem, previousVersion); } protected override void Unpublished(PublishContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Unpublished, context.ContentItem); + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Unpublished, context.ContentItem); } protected override void Removed(RemoveContentContext context) { - RecordAuditTrail(ContentAuditTrailEventProvider.Removed, context.ContentItem); + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Removed, context.ContentItem); } - private void RecordAuditTrail(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { + private void RecordAuditTrailEvent(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { var title = _contentManager.GetItemMetadata(content).DisplayText; var properties = new Dictionary { @@ -56,7 +56,7 @@ namespace Orchard.AuditTrail.Providers.Content { eventData["PreviousContentItemVersionId"] = previousContentItemVersion.Id; } - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString(CultureInfo.InvariantCulture)); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString(CultureInfo.InvariantCulture)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs index bb79ed7d0..c184f4596 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs @@ -13,27 +13,27 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { } public void ContentTypeCreated(dynamic context) { - RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.Created, context.ContentTypeDefinition); + RecordContentTypeAuditTrailEvent(ContentTypeAuditTrailEventProvider.Created, context.ContentTypeDefinition); } public void ContentTypeRemoved(dynamic context) { - RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.Removed, context.ContentTypeDefinition); + RecordContentTypeAuditTrailEvent(ContentTypeAuditTrailEventProvider.Removed, context.ContentTypeDefinition); } public void ContentPartCreated(dynamic context) { - RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.Created, context.ContentPartDefinition); + RecordContentPartAuditTrailEvent(ContentPartAuditTrailEventProvider.Created, context.ContentPartDefinition); } public void ContentPartRemoved(dynamic context) { - RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.Removed, context.ContentPartDefinition); + RecordContentPartAuditTrailEvent(ContentPartAuditTrailEventProvider.Removed, context.ContentPartDefinition); } public void ContentPartAttached(dynamic context) { - RecordContentTypePartAuditTrail(ContentTypeAuditTrailEventProvider.PartAdded, context.ContentTypeName, context.ContentPartName); + RecordContentTypePartAuditTrailEvent(ContentTypeAuditTrailEventProvider.PartAdded, context.ContentTypeName, context.ContentPartName); } public void ContentPartDetached(dynamic context) { - RecordContentTypePartAuditTrail(ContentTypeAuditTrailEventProvider.PartRemoved, context.ContentTypeName, context.ContentPartName); + RecordContentTypePartAuditTrailEvent(ContentTypeAuditTrailEventProvider.PartRemoved, context.ContentTypeName, context.ContentPartName); } public void ContentFieldAttached(dynamic context) { @@ -43,7 +43,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { {"ContentFieldTypeName", context.ContentFieldTypeName}, {"ContentFieldDisplayName", context.ContentFieldDisplayName} }; - _auditTrailManager.Record(ContentPartAuditTrailEventProvider.FieldAdded, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); + _auditTrailManager.CreateRecord(ContentPartAuditTrailEventProvider.FieldAdded, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); } public void ContentFieldDetached(dynamic context) { @@ -51,30 +51,30 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { {"ContentPartName", context.ContentPartName}, {"ContentFieldName", context.ContentFieldName} }; - _auditTrailManager.Record(ContentPartAuditTrailEventProvider.FieldRemoved, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); + _auditTrailManager.CreateRecord(ContentPartAuditTrailEventProvider.FieldRemoved, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); } - private void RecordContentTypeAuditTrail(string eventName, ContentTypeDefinition contentTypeDefinition) { + private void RecordContentTypeAuditTrailEvent(string eventName, ContentTypeDefinition contentTypeDefinition) { var eventData = new Dictionary { {"ContentTypeName", contentTypeDefinition.Name}, {"ContentTypeDisplayName", contentTypeDefinition.DisplayName}, }; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeDefinition.Name); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeDefinition.Name); } - private void RecordContentPartAuditTrail(string eventName, ContentPartDefinition contentPartDefinition) { + private void RecordContentPartAuditTrailEvent(string eventName, ContentPartDefinition contentPartDefinition) { var eventData = new Dictionary { {"ContentPartName", contentPartDefinition.Name} }; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartDefinition.Name); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartDefinition.Name); } - private void RecordContentTypePartAuditTrail(string eventName, string contentTypeName, string contentPartName) { + private void RecordContentTypePartAuditTrailEvent(string eventName, string contentTypeName, string contentPartName) { var eventData = new Dictionary { {"ContentTypeName", contentTypeName}, {"ContentPartName", contentPartName} }; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index b04a62333..f61106b3d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -51,11 +51,11 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { } private void RecordContentTypeAuditTrail(string eventName, IDictionary eventData, string contentTypeName) { - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); } private void RecordContentPartAuditTrail(string eventName, IDictionary eventData, string contentPartName) { - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartName); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: contentPartName); } } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs index 6ff66aa00..6da64a24d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs @@ -13,11 +13,11 @@ namespace Orchard.AuditTrail.Providers.Role { } public void Created(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.Created, context.Role.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.Created, context.Role.Name); } public void Removed(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.Removed, context.Role.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.Removed, context.Role.Name); } public void Renamed(dynamic context) { @@ -27,44 +27,35 @@ namespace Orchard.AuditTrail.Providers.Role { {"NewRoleName", (string)context.NewRoleName}, }; - RecordAuditTrail(RoleAuditTrailEventProvider.Renamed, context.Role.Name, properties: null, eventData:eventData); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.Renamed, context.Role.Name, properties: null, eventData:eventData); } public void PermissionAdded(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.PermissionAdded, context.Role.Name, context.Permission.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionAdded, (string) context.Role.Name, (IUser) context.Permission.Name); } public void PermissionRemoved(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.PermissionRemoved, context.Role.Name, context.Permission.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionRemoved, (string) context.Role.Name, (IUser) context.Permission.Name); } public void UserAdded(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.UserAdded, context.Role.Name, context.User); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserAdded, (string) context.Role.Name, (IUser) context.User); } public void UserRemoved(dynamic context) { - RecordAuditTrail(RoleAuditTrailEventProvider.UserRemoved, context.Role.Name, context.User); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserRemoved, (string) context.Role.Name, (IUser) context.User); } - private void RecordAuditTrail(string eventName, string roleName) { + private void RecordAuditTrailEvent(string eventName, string roleName) { var eventData = new Dictionary { {"RoleName", roleName} }; - RecordAuditTrail(eventName, roleName, properties: null, eventData: eventData); - } - - private void RecordAuditTrail(string eventName, string roleName, string permissionName) { - var eventData = new Dictionary { - {"RoleName", roleName}, - {"PermissionName", permissionName} - }; - - RecordAuditTrail(eventName, roleName, properties: null, eventData: eventData); + RecordAuditTrailEvent(eventName, roleName, properties: null, eventData: eventData); } - private void RecordAuditTrail(string eventName, string roleName, IUser user) { + private void RecordAuditTrailEvent(string eventName, string roleName, IUser user) { var properties = new Dictionary { {"User", user} @@ -75,11 +66,11 @@ namespace Orchard.AuditTrail.Providers.Role { {"UserName", user.UserName} }; - RecordAuditTrail(eventName, roleName, properties, eventData); + RecordAuditTrailEvent(eventName, roleName, properties, eventData); } - private void RecordAuditTrail(string eventName, string roleName, IDictionary properties, IDictionary eventData) { - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "role", eventFilterData: roleName); + private void RecordAuditTrailEvent(string eventName, string roleName, IDictionary properties, IDictionary eventData) { + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "role", eventFilterData: roleName); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs index bd5fe80b0..185f0d156 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs @@ -25,7 +25,7 @@ namespace Orchard.AuditTrail.Providers.User { {"UserName", userNameOrEmail} }; - _auditTrailManager.Record(UserAuditTrailEventProvider.LogInFailed, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "user", eventFilterData: userNameOrEmail); + _auditTrailManager.CreateRecord(UserAuditTrailEventProvider.LogInFailed, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "user", eventFilterData: userNameOrEmail); } public void ChangedPassword(IUser user) { @@ -43,7 +43,7 @@ namespace Orchard.AuditTrail.Providers.User { {"UserName", user.UserName} }; - _auditTrailManager.Record(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.UserName); + _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.UserName); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs index ae889fc4a..643efe12e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -18,7 +18,7 @@ namespace Orchard.AuditTrail.Services { public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) { var eventData = _serializer.Deserialize(record.EventData); - var descriptor = _auditTrailManager.Describe(record.Event); + var descriptor = _auditTrailManager.DescribeEvent(record.Event); var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData, Descriptor: descriptor); var metaData = (ShapeMetadata)auditTrailEventShape.Metadata; metaData.DisplayType = displayType; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 533835b49..57fe6605a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -56,12 +56,12 @@ namespace Orchard.AuditTrail.Services { } switch (orderBy) { - default: - query = query.OrderByDescending(x => x.CreatedUtc).ThenByDescending(x => x.Id); - break; case AuditTrailOrderBy.EventAscending: query = query.OrderBy(x => x.Event).ThenByDescending(x => x.Id); break; + default: + query = query.OrderByDescending(x => x.CreatedUtc).ThenByDescending(x => x.Id); + break; } var totalItemCount = query.Count(); @@ -79,9 +79,9 @@ namespace Orchard.AuditTrail.Services { return _auditTrailRepository.Get(id); } - public AuditTrailEventRecordResult Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { - var eventDescriptor = Describe(eventName); - if(!IsEnabled(eventDescriptor)) + public AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { + var eventDescriptor = DescribeEvent(eventName); + if(!IsEventEnabled(eventDescriptor)) return new AuditTrailEventRecordResult { Record = null, IsDisabled = true @@ -119,7 +119,7 @@ namespace Orchard.AuditTrail.Services { }; } - private bool IsEnabled(AuditTrailEventDescriptor eventDescriptor) { + private bool IsEventEnabled(AuditTrailEventDescriptor eventDescriptor) { var settingsDictionary = _cacheManager.Get("AuditTrail.EventSettings", context => { context.Monitor(_signals.When("AuditTrail.EventSettings")); return _siteService.GetSiteSettings().As().EventSettings.ToDictionary(x => x.EventName); @@ -128,19 +128,19 @@ namespace Orchard.AuditTrail.Services { return setting != null ? setting.IsEnabled : eventDescriptor.IsEnabledByDefault; } - public IEnumerable Describe() { + public IEnumerable DescribeCategories() { var context = new DescribeContext(); _providers.Describe(context); return context.Describe(); } - public AuditTrailEventDescriptor Describe(string eventName) where T:IAuditTrailEventProvider { + public AuditTrailEventDescriptor DescribeEvent(string eventName) where T:IAuditTrailEventProvider { var fullyQualifiedEventName = EventNameHelper.GetFullyQualifiedEventName(eventName); - return Describe(fullyQualifiedEventName); + return DescribeEvent(fullyQualifiedEventName); } - public AuditTrailEventDescriptor Describe(string fullyQualifiedEventName) { - var categoryDescriptors = Describe(); + public AuditTrailEventDescriptor DescribeEvent(string fullyQualifiedEventName) { + var categoryDescriptors = DescribeCategories(); var eventDescriptorQuery = from c in categoryDescriptors from e in c.Events where e.Event == fullyQualifiedEventName @@ -148,7 +148,7 @@ namespace Orchard.AuditTrail.Services { var eventDescriptors = eventDescriptorQuery.ToArray(); if (!eventDescriptors.Any()) { - throw new ArgumentException(String.Format("No event named '{0}' exists.", fullyQualifiedEventName)); + throw new ArgumentException(String.Format("No event named '{0}' exists.", fullyQualifiedEventName), "fullyQualifiedEventName"); } return eventDescriptors.First(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index 9ed5e1a42..7c671318f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -38,7 +38,7 @@ namespace Orchard.AuditTrail.Services { Logger.Debug("Starting audit trail trimming operation."); var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.Threshold)); - Logger.Debug("Audit trail trimming operation completed. {0} Records were deleted.", deletedRecords.Count()); + Logger.Debug("Audit trail trimming operation completed. {0} records were deleted.", deletedRecords.Count()); Settings.LastRunUtc = _clock.UtcNow; } catch (Exception ex) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs index 8f37e91fe..a9192ab16 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/EventDataSerializer.cs @@ -13,7 +13,7 @@ namespace Orchard.AuditTrail.Services { return xml.ToString(SaveOptions.DisableFormatting); } catch (Exception ex) { - Logger.Error(ex, "Error during serialization of eventData"); + Logger.Error(ex, "Error during serialization of event data."); } return null; } @@ -28,7 +28,7 @@ namespace Orchard.AuditTrail.Services { return JsonConvert.DeserializeObject>(json); } catch (Exception ex) { - Logger.Error(ex, "Error during deserialization of eventData"); + Logger.Error(ex, "Error during deserialization of event data."); } return new Dictionary(); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 91e1d1812..8d309a27d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -34,13 +34,13 @@ namespace Orchard.AuditTrail.Services { /// The name of a custom key to use when filtering events. /// The value of a custom filter key to filter on. /// Returns the created audit trail event record if the specified event was not disabled. - AuditTrailEventRecordResult Record(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; + AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; /// /// Describes all audit trail events provided by the system. /// /// Returns a list of audit trail category descriptors. - IEnumerable Describe(); + IEnumerable DescribeCategories(); /// /// Describes a single audit trail event. @@ -48,14 +48,14 @@ namespace Orchard.AuditTrail.Services { /// The scope of the specified event name. /// The shorthand name of the event. /// Returns a single audit trail event descriptor. - AuditTrailEventDescriptor Describe(string eventName) where T : IAuditTrailEventProvider; + AuditTrailEventDescriptor DescribeEvent(string eventName) where T : IAuditTrailEventProvider; /// /// Describes a single audit trail event. /// /// The fully qualified event name to describe. /// Returns a single audit trail event descriptor. - AuditTrailEventDescriptor Describe(string fullyQualifiedEventName); + AuditTrailEventDescriptor DescribeEvent(string fullyQualifiedEventName); /// /// Trims the audit trail by deleting all records older than the specified threshold. diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCategoryDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCategoryDescriptor.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs From 9fd6c88afda23e15b136b6bdc4584141882f58a1 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Mon, 30 Jun 2014 00:19:17 +0200 Subject: [PATCH 035/116] Incremental work. --- .../ImportExport/AuditTrailExportHandler.cs | 12 +++++------- .../ImportExport/AuditTrailExportStep.cs | 7 +++---- .../ImportExport/AuditTrailImportHandler.cs | 2 ++ .../Modules/Orchard.AuditTrail/Module.txt | 17 +++++++++++------ .../Orchard.AuditTrail.csproj | 4 ++++ .../Parts.AuditTrail.Comment.cshtml | 8 +++----- src/Orchard.Web/Orchard.Web.csproj | 2 +- 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs index 763b6e31e..8f735bb08 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs @@ -4,14 +4,12 @@ using System.Linq; using System.Xml.Linq; using Orchard.AuditTrail.Models; using Orchard.Data; +using Orchard.Environment.Extensions; using Orchard.Events; +using Orchard.ImportExport.Services; namespace Orchard.AuditTrail.ImportExport { - public interface IExportEventHandler : IEventHandler { - void Exporting(dynamic context); - void Exported(dynamic context); - } - + [OrchardFeature("Orchard.AuditTrail.ImportExport")] public class AuditTrailExportEventHandler : IExportEventHandler { private readonly IRepository _auditTrailEventRepository; @@ -19,10 +17,10 @@ namespace Orchard.AuditTrail.ImportExport { _auditTrailEventRepository = auditTrailEventRepository; } - public void Exporting(dynamic context) { + public void Exporting(ExportContext context) { } - public void Exported(dynamic context) { + public void Exported(ExportContext context) { if (!((IEnumerable)context.ExportOptions.CustomSteps).Contains("AuditTrail")) { return; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs index 8caba42c4..dc0291953 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; +using Orchard.Environment.Extensions; using Orchard.Events; +using Orchard.ImportExport.Services; namespace Orchard.AuditTrail.ImportExport { - public interface ICustomExportStep : IEventHandler { - void Register(IList steps); - } - + [OrchardFeature("Orchard.AuditTrail.ImportExport")] public class AuditTrailExportStep : ICustomExportStep { public void Register(IList steps) { steps.Add("AuditTrail"); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs index 84dc8e8d7..9fffd5b05 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs @@ -2,10 +2,12 @@ using Orchard.AuditTrail.Models; using Orchard.ContentManagement; using Orchard.Data; +using Orchard.Environment.Extensions; using Orchard.Recipes.Models; using Orchard.Recipes.Services; namespace Orchard.AuditTrail.ImportExport { + [OrchardFeature("Orchard.AuditTrail.ImportExport")] public class AuditTrailImportHandler : Component, IRecipeHandler { private readonly IRepository _auditTrailEventRepository; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 1d50d3a86..72fb53bbf 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -1,18 +1,23 @@ -Name: AuditTrail +Name: Audit Trail AntiForgery: enabled Author: The Orchard Team Website: http://orchardproject.net Version: 1.8.1 OrchardVersion: 1.8 -Description: Logs user initiated events, such as content changes, providing a trail for auditing. +Description: Provides a log for recording and viewing back-end changes. Features: Orchard.AuditTrail: - Name: AuditTrail - Description: Provides the core audit trail framework. + Name: Audit Trail + Description: Provides a log for recording and viewing back-end changes. Category: Security Dependencies: Orchard.Users, Orchard.Roles, Orchard.ContentTypes + Orchard.AuditTrail.ImportExport: + Name: Audit Trail Import Export + Description: Provides import/export functionality for the Audit Trail feature. + Category: Security + Dependencies: Orchard.AuditTrail, Orchard.ImportExport Orchard.AuditTrail.Trimming: - Name: AuditTrail Trimming - Description: A background task that trims the audit trail. + Name: Audit Trail Trimming + Description: Provides a background task that regularly deletes old audit trail records. Category: Security Dependencies: Orchard.AuditTrail \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 7c8d43ca5..e0e6a1d14 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -138,6 +138,10 @@ {9916839C-39FC-4CEB-A5AF-89CA7E87119F} Orchard.Core + + {fe5c5947-d2d5-42c5-992a-13d672946135} + Orchard.ImportExport + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml index ea4d776fa..3cb48fcb0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml @@ -1,8 +1,6 @@ @model Orchard.AuditTrail.Models.AuditTrailPart
-
- @Html.LabelFor(m => m.Comment, T("Audit Trail Comment")) - @Html.TextBoxFor(m => m.Comment, new { @class = "text large" }) - @T("Optionally provide a comment about this change. This comment will be stored as part of an audit trail event.") -
+ @Html.LabelFor(m => m.Comment, T("Comment")) + @Html.TextAreaFor(m => m.Comment) + @T("Optionally provide a comment about this change for the audit trail.")
\ No newline at end of file diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index e2183ce23..66e4f2712 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -224,7 +224,7 @@ False 30321 /OrchardLocal - http://localhost:30321/OrchardLocal + http://localhost:30322/OrchardLocal False False From 3ec88e55be0efd38490b4d483907751bc06f7ccd Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 11:56:42 -0700 Subject: [PATCH 036/116] 149: Added Context column. --- .../Providers/Content/DiffGramAnalyzer.cs | 10 +++++++--- .../Orchard.AuditTrail/Providers/Content/DiffNode.cs | 2 +- .../Views/AuditTrailEvent-Content.cshtml | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index 49be713b7..5e5989b91 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -57,7 +57,7 @@ namespace Orchard.AuditTrail.Providers.Content { yield return new DiffNode { Type = DiffType.Change, - ElementName = attributeName, + Context = BuildContextName(stack, attributeName), Previous = originalValue, Current = currentValue }; @@ -71,7 +71,7 @@ namespace Orchard.AuditTrail.Providers.Content { yield return new DiffNode { Type = DiffType.Change, - ElementName = currentElement.Name.ToString(), + Context = currentElement.Name.ToString(), Previous = originalContent, Current = currentContent }; @@ -80,7 +80,7 @@ namespace Orchard.AuditTrail.Providers.Content { case "add": reader.Read(); var addedElementContent = reader.ReadElementContentAsString(); - yield return new DiffNode { Type = DiffType.Addition, ElementName = reader.Name, Current = addedElementContent }; + yield return new DiffNode { Type = DiffType.Addition, Context = reader.Name, Current = addedElementContent }; break; } } @@ -94,5 +94,9 @@ namespace Orchard.AuditTrail.Providers.Content { } } } + + private string BuildContextName(IEnumerable stack, string attributeName) { + return String.Join("/", stack.Reverse().Skip(1).Select(x => x.Name)) + "/" + attributeName; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs index b7e88b108..52369de66 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffNode.cs @@ -1,7 +1,7 @@ namespace Orchard.AuditTrail.Providers.Content { public class DiffNode { public DiffType Type { get; set; } - public string ElementName { get; set; } + public string Context { get; set; } public string Previous { get; set; } public string Current { get; set; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 323bc0b56..b70cf9496 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -20,7 +20,7 @@ @T("Diff Type") - @T("Element") + @T("Context") @T("Before") @T("After") @@ -35,7 +35,7 @@ foreach (var node in diffNodes) { @T(node.Type.ToString()) - @node.ElementName + @node.Context @node.Previous @node.Current From c1f91d41b8e3c25f13827c26fe08587b024a9354 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 16:34:29 -0700 Subject: [PATCH 037/116] 151: Implemented pluggable filter UI. 153: Added Order By Category. --- .../Controllers/AdminController.cs | 16 +- .../Drivers/AuditTrailPartDriver.cs | 7 +- .../Helpers/DateTimeHelper.cs | 21 ++ .../Helpers/FiltersHelper.cs | 12 + .../Helpers/StringConversionHelper.cs | 16 + .../Models/DescribeContext.cs | 30 -- .../Orchard.AuditTrail.csproj | 30 +- .../Content/AuditTrailEventHandler.cs | 5 +- .../Content/ContentAuditTrailEventProvider.cs | 36 ++- .../Providers/Content/GlobalContentHandler.cs | 8 +- .../ContentPartAuditTrailEventProvider.cs | 1 + .../ContentTypeAuditTrailEventProvider.cs | 32 +- .../Role/RoleAuditTrailEventProvider.cs | 1 + .../User/UserAuditTrailEventProvider.cs | 1 + .../Services/AuditTrailEventHandlerBase.cs | 9 + .../Services/AuditTrailEventProviderBase.cs | 2 +- .../Services/AuditTrailManager.cs | 65 +++- .../Services/CommonAuditTrailEventHandler.cs | 50 +++ .../Services/IAuditTrailEventHandler.cs | 4 +- .../Services/IAuditTrailEventProvider.cs | 1 + .../Services/IAuditTrailManager.cs | 18 +- .../Models/AuditTrailCategoryDescriptor.cs | 3 +- .../Models/AuditTrailContext.cs | 2 +- .../Models/AuditTrailCreateContext.cs | 2 +- .../Models/AuditTrailEventDescriptor.cs | 2 +- .../Models/AuditTrailFilterParameters.cs | 6 +- .../Models/AuditTrailOrderBy.cs | 3 +- .../Services/Models/DescribeContext.cs | 51 ++++ .../{ => Services}/Models/DescribeFor.cs | 3 +- .../Services/Models/DisplayFilterContext.cs | 15 + .../Services/Models/Filters.cs | 21 ++ .../Services/Models/QueryFilterContext.cs | 14 + .../Shapes/AuditTrailShapes.cs | 32 ++ .../Orchard.AuditTrail/Styles/admin.css | 12 +- .../Orchard.AuditTrail/Styles/custom-grid.css | 285 ++++++++++++++++++ .../ViewModels/AuditTrailDetailsViewModel.cs | 1 + .../AuditTrailEventSummaryViewModel.cs | 1 + .../ViewModels/AuditTrailViewModel.cs | 8 +- ....cs => CommonAuditTrailFilterViewModel.cs} | 11 +- .../Views/Admin/Index.cshtml | 55 ++-- .../Views/AuditTrailFilter-Common-Date.cshtml | 11 + .../Views/AuditTrailFilter-Common-User.cshtml | 4 + .../Views/AuditTrailFilter-ContentItem.cshtml | 11 + .../Views/AuditTrailFilter-ContentType.cshtml | 10 + .../Parts.AuditTrailSettings.cshtml | 6 +- .../Views/Parts.AuditTrail.Link.cshtml | 2 +- .../Views/Parts.AuditTrail.cshtml | 2 +- ...ts.Contents.AuditTrail.SummaryAdmin.cshtml | 2 +- 48 files changed, 819 insertions(+), 121 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventHandlerBase.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailContext.cs (91%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailCreateContext.cs (69%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailEventDescriptor.cs (88%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailFilterParameters.cs (60%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/AuditTrailOrderBy.cs (53%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeContext.cs rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Services}/Models/DescribeFor.cs (94%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/QueryFilterContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css rename src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/{AuditTrailFilterViewModel.cs => CommonAuditTrailFilterViewModel.cs} (52%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 3b147b4ba..bf69ac027 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Web.Mvc; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.ViewModels; using Orchard.Localization.Services; using Orchard.Security; @@ -27,20 +28,16 @@ namespace Orchard.AuditTrail.Controllers { public dynamic New { get; private set; } - public ActionResult Index(PagerParameters pagerParameters, AuditTrailFilterViewModel filterParameters) { + public ActionResult Index(PagerParameters pagerParameters, AuditTrailOrderBy? orderBy = null) { if(!_authorizer.Authorize(Permissions.ViewAuditTrail)) return new HttpUnauthorizedResult(); var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters); - var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { - UserName = filterParameters.UserName, - FilterKey = filterParameters.FilterKey, - FilterValue = filterParameters.FilterValue, - From = _dateServices.ConvertFromLocalString(filterParameters.From.Date, filterParameters.From.Time), - To = _dateServices.ConvertFromLocalString(filterParameters.To.Date, filterParameters.To.Time), - }, filterParameters.OrderBy); + var filters = Filters.From(Request.QueryString); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, filters, orderBy ?? AuditTrailOrderBy.DateDescending); var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); + var filterLayout = _auditTrailManager.BuildFilterDisplays(filters); var eventDescriptorsQuery = from c in _auditTrailManager.DescribeCategories() from e in c.Events @@ -60,7 +57,8 @@ namespace Orchard.AuditTrail.Controllers { var viewModel = new AuditTrailViewModel { Records = recordViewModelsQuery.ToArray(), Pager = pagerShape, - Filter = filterParameters + OrderBy = orderBy ?? AuditTrailOrderBy.DateDescending, + FilterLayout = filterLayout }; return View(viewModel); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 5014fb060..128ea8726 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -2,7 +2,9 @@ using System.Globalization; using System.Linq; using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Providers.Content; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.Settings; using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; @@ -45,10 +47,7 @@ namespace Orchard.AuditTrail.Drivers { if (settings.ShowAuditTrail) { results.Add(ContentShape("Parts_AuditTrail", () => { var pager = new Pager(_services.WorkContext.CurrentSite, null, null); - var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, new AuditTrailFilterParameters { - FilterKey = "content", - FilterValue = part.Id.ToString(CultureInfo.InvariantCulture) - }); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, ContentAuditTrailEventProvider.CreateFilters(part.Id)); var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); var eventDescriptors = from c in _auditTrailManager.DescribeCategories() from e in c.Events diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs new file mode 100644 index 000000000..0b9e0a349 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs @@ -0,0 +1,21 @@ +using System; + +namespace Orchard.AuditTrail.Helpers { + public static class DateTimeHelper { + public static DateTime? Earliest(this DateTime? value) { + if (value == null) + return null; + + var v = value.Value; + return new DateTime(v.Year, v.Month, v.Day, 0, 0, 0, 0, v.Kind); + } + + public static DateTime? Latest(this DateTime? value) { + if (value == null) + return null; + + var v = value.Value; + return new DateTime(v.Year, v.Month, v.Day, 23, 59, 59, 999, v.Kind); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs new file mode 100644 index 000000000..04c7912dc --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs @@ -0,0 +1,12 @@ +using Orchard.AuditTrail.Services.Models; + +namespace Orchard.AuditTrail.Helpers { + public static class FiltersHelper { + public static string Get(this Filters filters, string key) { + if (!filters.ContainsKey(key)) + return null; + + return filters[key]; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs new file mode 100644 index 000000000..f3f2b40db --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs @@ -0,0 +1,16 @@ +using System; + +namespace Orchard.AuditTrail.Helpers { + public static class StringConversionHelper { + public static int? ToInt32(this string value) { + if (String.IsNullOrWhiteSpace(value)) + return null; + + int i; + if(!Int32.TryParse(value, out i)) + return null; + + return i; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs deleted file mode 100644 index fd692069a..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeContext.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Orchard.Localization; - -namespace Orchard.AuditTrail.Models { - public class DescribeContext { - private readonly Dictionary _describes = new Dictionary(); - - public IEnumerable Describe() { - var query = - from d in _describes.Values - select new AuditTrailCategoryDescriptor { - Category = d.Category, - Name = d.Name, - Events = d.Events - }; - - return query.ToArray(); - } - - public DescribeFor For(string category, LocalizedString name) { - DescribeFor describeFor; - if (!_describes.TryGetValue(category, out describeFor)) { - describeFor = new DescribeFor(category, name); - _describes[category] = describeFor; - } - return describeFor; - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index e0e6a1d14..471b08fcc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -80,6 +80,7 @@ + @@ -128,6 +129,10 @@ + + + +
@@ -149,17 +154,26 @@ + + + + + + + + + @@ -175,7 +189,7 @@ - + @@ -194,18 +208,18 @@ - + - - - - + + + + - - + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs index 7fa9130a2..6f3388fe3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs @@ -1,10 +1,11 @@ using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; using Orchard.ContentManagement; namespace Orchard.AuditTrail.Providers.Content { - public class AuditTrailEventHandler : IAuditTrailEventHandler { - public void Create(AuditTrailCreateContext context) { + public class ContentAuditTrailEventHandler : AuditTrailEventHandlerBase { + public override void Create(AuditTrailCreateContext context) { var content = context.Properties.ContainsKey("Content") ? (IContent)context.Properties["Content"] : default(IContent); var auditTrailPart = content != null ? content.As() : default(AuditTrailPart); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs index 69239aeda..4b3f2819b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs @@ -1,14 +1,29 @@ -using Orchard.AuditTrail.Models; +using System.Globalization; +using System.Linq; +using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; +using Orchard.ContentManagement; namespace Orchard.AuditTrail.Providers.Content { public class ContentAuditTrailEventProvider : AuditTrailEventProviderBase { + private readonly IContentManager _contentManager; + public ContentAuditTrailEventProvider(IContentManager contentManager) { + _contentManager = contentManager; + } + public const string Created = "Created"; public const string Saved = "Saved"; public const string Published = "Published"; public const string Unpublished = "Unpublished"; public const string Removed = "Removed"; + public static Filters CreateFilters(int contentId) { + return new Filters { + {"content", contentId.ToString(CultureInfo.InvariantCulture)} + }; + } + public override void Describe(DescribeContext context) { context.For("Content", T("Content")) .Event(this, Created, T("Created"), T("Content was created."), enableByDefault: true) @@ -16,6 +31,25 @@ namespace Orchard.AuditTrail.Providers.Content { .Event(this, Published, T("Published"), T("Content was published."), enableByDefault: true) .Event(this, Unpublished, T("Unpublished"), T("Content was unpublished."), enableByDefault: true) .Event(this, Removed, T("Removed"), T("Content was deleted."), enableByDefault: true); + + context.QueryFilter(QueryFilter); + context.DisplayFilter(DisplayFilter); + } + + private void QueryFilter(QueryFilterContext context) { + if (!context.Filters.ContainsKey("content")) + return; + + var contentId = context.Filters["content"].ToInt32(); + context.Query = context.Query.Where(x => x.EventFilterKey == "content" && x.EventFilterData == contentId.ToString()); + } + + private void DisplayFilter(DisplayFilterContext context) { + var contentItemId = context.Filters.Get("content").ToInt32(); + var contentItem = contentItemId != null ? _contentManager.Get(contentItemId.Value, VersionOptions.Latest) : default(ContentItem); + var filterDisplay = context.ShapeFactory.AuditTrailFilter__ContentItem(ContentItem: contentItem); + + context.FilterLayout.TripleSecond.Add(filterDisplay); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index d795f51bc..99c94ee66 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -56,7 +56,13 @@ namespace Orchard.AuditTrail.Providers.Content { eventData["PreviousContentItemVersionId"] = previousContentItemVersion.Id; } - _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", eventFilterData: content.Id.ToString(CultureInfo.InvariantCulture)); + _auditTrailManager.CreateRecord( + eventName, + _wca.GetContext().CurrentUser, + properties, + eventData, + eventFilterKey: "content", + eventFilterData: content.Id.ToString(CultureInfo.InvariantCulture)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs index 6b5427a3a..52a4fae68 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -1,5 +1,6 @@ using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Providers.ContentDefinition { public class ContentPartAuditTrailEventProvider : AuditTrailEventProviderBase { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 4ef7a0222..55537237b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -1,8 +1,18 @@ -using Orchard.AuditTrail.Models; +using System; +using System.Linq; +using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; +using Orchard.ContentManagement.MetaData; namespace Orchard.AuditTrail.Providers.ContentDefinition { public class ContentTypeAuditTrailEventProvider : AuditTrailEventProviderBase { + private readonly IContentDefinitionManager _contentDefinitionManager; + + public ContentTypeAuditTrailEventProvider(IContentDefinitionManager contentDefinitionManager) { + _contentDefinitionManager = contentDefinitionManager; + } + public const string Created = "Created"; public const string Removed = "Removed"; public const string PartAdded = "PartAdded"; @@ -18,6 +28,26 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { .Event(this, PartRemoved, T("Part removed"), T("Content Part was removed."), enableByDefault: true) .Event(this, TypeSettingsUpdated, T("Type Settings updated"), T("Content Type settings were updated."), enableByDefault: true) .Event(this, PartSettingsUpdated, T("Part Settings updated"), T("Content Part settings were updated."), enableByDefault: true); + + context.QueryFilter(QueryFilter); + context.DisplayFilter(DisplayFilter); + } + + private void QueryFilter(QueryFilterContext context) { + var contentType = context.Filters.Get("contenttype"); + + if(String.IsNullOrWhiteSpace(contentType)) + return; + + context.Query = context.Query.Where(x => x.EventFilterKey == "contenttype" && x.EventFilterData == contentType); + } + + private void DisplayFilter(DisplayFilterContext context) { + var filterDisplay = context.ShapeFactory.AuditTrailFilter__ContentType( + ContentType: context.Filters.Get("contenttype"), + ContentTypes: _contentDefinitionManager.ListTypeDefinitions().OrderBy(x => x.DisplayName).ToArray()); + + context.FilterLayout.TripleFirst.Add(filterDisplay); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs index 8f7a921a7..ebac1ea51 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs @@ -1,5 +1,6 @@ using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Providers.Role { public class RoleAuditTrailEventProvider : AuditTrailEventProviderBase { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs index 7586775b9..38325709a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs @@ -1,5 +1,6 @@ using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Providers.User { public class UserAuditTrailEventProvider : AuditTrailEventProviderBase { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventHandlerBase.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventHandlerBase.cs new file mode 100644 index 000000000..68df698d4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventHandlerBase.cs @@ -0,0 +1,9 @@ +using Orchard.AuditTrail.Services.Models; + +namespace Orchard.AuditTrail.Services { + public class AuditTrailEventHandlerBase : Component, IAuditTrailEventHandler { + public virtual void Create(AuditTrailCreateContext context) {} + public virtual void Filter(QueryFilterContext context) {} + public virtual void DisplayFilter(DisplayFilterContext context) { } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs index f22326613..e68e9d284 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventProviderBase.cs @@ -1,4 +1,4 @@ -using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Services { public abstract class AuditTrailEventProviderBase : Component, IAuditTrailEventProvider { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 57fe6605a..1c384dc08 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -1,13 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Security.Cryptography; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; using Orchard.Caching; using Orchard.Collections; using Orchard.ContentManagement; using Orchard.Data; +using Orchard.DisplayManagement; using Orchard.Security; using Orchard.Services; using Orchard.Settings; @@ -22,6 +23,7 @@ namespace Orchard.AuditTrail.Services { private readonly ICacheManager _cacheManager; private readonly ISiteService _siteService; private readonly ISignals _signals; + private readonly IShapeFactory _shapeFactory; public AuditTrailManager( IRepository auditTrailRepository, @@ -31,7 +33,8 @@ namespace Orchard.AuditTrail.Services { IEventDataSerializer serializer, ICacheManager cacheManager, ISiteService siteService, - ISignals signals) { + ISignals signals, + IShapeFactory shapeFactory) { _auditTrailRepository = auditTrailRepository; _providers = providers; @@ -41,24 +44,40 @@ namespace Orchard.AuditTrail.Services { _cacheManager = cacheManager; _siteService = siteService; _signals = signals; + _shapeFactory = shapeFactory; } - public IPageOfItems GetRecords(int page, int pageSize, AuditTrailFilterParameters filter = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending) { + public IPageOfItems GetRecords( + int page, + int pageSize, + Filters filters = null, + AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending) { var query = _auditTrailRepository.Table; + - if (filter != null) { - if (!String.IsNullOrWhiteSpace(filter.FilterKey)) query = query.Where(x => x.EventFilterKey == filter.FilterKey); - if (!String.IsNullOrWhiteSpace(filter.FilterValue)) query = query.Where(x => x.EventFilterData == filter.FilterValue); - if (!String.IsNullOrWhiteSpace(filter.UserName)) query = query.Where(x => x.UserName == filter.UserName); - if (filter.From != null) query = query.Where(x => x.CreatedUtc >= filter.From); - if (filter.To != null) query = query.Where(x => x.CreatedUtc <= filter.To); + if (filters != null) { + var filterContext = new QueryFilterContext(query, filters); + + // Invoke event handlers. + _auditTrailEventHandlers.Filter(filterContext); + + // Give each provider a chance to modify the query. + var providersContext = DescribeProviders(); + foreach (var queryFilter in providersContext.QueryFilters) { + queryFilter(filterContext); + } + + query = filterContext.Query; } switch (orderBy) { case AuditTrailOrderBy.EventAscending: query = query.OrderBy(x => x.Event).ThenByDescending(x => x.Id); break; + case AuditTrailOrderBy.CategoryAscending: + query = query.OrderBy(x => x.Category).ThenByDescending(x => x.Id); + break; default: query = query.OrderByDescending(x => x.CreatedUtc).ThenByDescending(x => x.Id); break; @@ -79,6 +98,27 @@ namespace Orchard.AuditTrail.Services { return _auditTrailRepository.Get(id); } + public dynamic BuildFilterDisplays(Filters filters) { + var layout = (dynamic)_shapeFactory.Create("AuditTrailFilters", Arguments.From(new { + TripleFirst = _shapeFactory.Create("AuditTrailFilters_TripleFirst"), + TripleSecond = _shapeFactory.Create("AuditTrailFilters_TripleSecond"), + TripleThird = _shapeFactory.Create("AuditTrailFilters_TripleThird") + })); + var displayContext = new DisplayFilterContext(_shapeFactory, filters, layout); + + // Invoke event handlers. + _auditTrailEventHandlers.DisplayFilter(displayContext); + + // Give each provider a chance to provide a filter display. + var providersContext = DescribeProviders(); + + foreach (var action in providersContext.FilterDisplays) { + action(displayContext); + } + + return layout; + } + public AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { var eventDescriptor = DescribeEvent(eventName); if(!IsEventEnabled(eventDescriptor)) @@ -129,9 +169,14 @@ namespace Orchard.AuditTrail.Services { } public IEnumerable DescribeCategories() { + var context = DescribeProviders(); + return context.Describe(); + } + + public DescribeContext DescribeProviders() { var context = new DescribeContext(); _providers.Describe(context); - return context.Describe(); + return context; } public AuditTrailEventDescriptor DescribeEvent(string eventName) where T:IAuditTrailEventProvider { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs new file mode 100644 index 000000000..2e2ec0b7b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs @@ -0,0 +1,50 @@ +using System; +using System.Linq; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Services.Models; +using Orchard.Core.Common.ViewModels; +using Orchard.Localization.Services; + +namespace Orchard.AuditTrail.Services { + public class CommonAuditTrailEventHandler : AuditTrailEventHandlerBase { + private readonly Lazy _auditTrailManager; + private readonly IDateServices _dateServices; + + public CommonAuditTrailEventHandler(Lazy auditTrailManager, IDateServices dateServices) { + _auditTrailManager = auditTrailManager; + _dateServices = dateServices; + } + + public override void Filter(QueryFilterContext context) { + // Common filters (username, from and to). + var userName = context.Filters.Get("username"); + var fromDate = context.Filters.Get("from.Date"); + var fromTime = context.Filters.Get("from.Time"); + var toDate = context.Filters.Get("to.Date"); + var toTime = context.Filters.Get("to.Time"); + var from = _dateServices.ConvertFromLocalString(fromDate, fromTime).Earliest(); + var to = _dateServices.ConvertFromLocalString(toDate, toTime).Latest(); + var query = context.Query; + + if (!String.IsNullOrWhiteSpace(userName)) query = query.Where(x => x.UserName == userName); + if (from != null) query = query.Where(x => x.CreatedUtc >= from); + if (to != null) query = query.Where(x => x.CreatedUtc <= to); + + context.Query = query; + } + + public override void DisplayFilter(DisplayFilterContext context) { + // Common filters (username, from and to). + var userName = context.Filters.Get("username"); + var fromDate = context.Filters.Get("from.Date"); + var toDate = context.Filters.Get("to.Date"); + var userNameFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__User(UserName: userName); + var dateFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Date( + From: new DateTimeEditor {Date = fromDate, ShowDate = true}, + To: new DateTimeEditor {Date = toDate, ShowDate = true}); + + context.FilterLayout.TripleFirst.Add(dateFilterDisplay); + context.FilterLayout.TripleSecond.Add(userNameFilterDisplay); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs index c27cfe6fa..9f0696695 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventHandler.cs @@ -1,8 +1,10 @@ -using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; using Orchard.Events; namespace Orchard.AuditTrail.Services { public interface IAuditTrailEventHandler : IEventHandler { void Create(AuditTrailCreateContext context); + void Filter(QueryFilterContext context); + void DisplayFilter(DisplayFilterContext context); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs index babfdcead..a8b0325c4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailEventProvider.cs @@ -1,4 +1,5 @@ using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; using Orchard.Events; namespace Orchard.AuditTrail.Services { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 8d309a27d..ba9d1e52a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; using Orchard.Collections; using Orchard.Security; @@ -12,9 +13,9 @@ namespace Orchard.AuditTrail.Services { /// The page number to get records from. /// The number of records to get. /// The value to order by. - /// Optional. An object to filter the records on. + /// Optional. An object to filter the records on. /// Returns a page of event records. - IPageOfItems GetRecords(int page, int pageSize, AuditTrailFilterParameters filter = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending); + IPageOfItems GetRecords(int page, int pageSize, Filters filters = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending); ///
/// Returns a single event record by ID. @@ -22,6 +23,13 @@ namespace Orchard.AuditTrail.Services { /// The event record ID. /// Returns a single event record by ID. AuditTrailEventRecord GetRecord(int id); + + /// + /// Builds a shape tree of filter displays. + /// + /// Input for each filter builder. + /// Returns a tree of shapes. + dynamic BuildFilterDisplays(Filters filters); /// /// Records an audit trail event. @@ -42,6 +50,11 @@ namespace Orchard.AuditTrail.Services { /// Returns a list of audit trail category descriptors. IEnumerable DescribeCategories(); + /// + /// Describes all audit trail event providers. + /// + DescribeContext DescribeProviders(); + /// /// Describes a single audit trail event. /// @@ -62,5 +75,6 @@ namespace Orchard.AuditTrail.Services { /// /// Returns the deleted records. IEnumerable Trim(TimeSpan threshold); + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs index 1a90f6ce3..492b27aac 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCategoryDescriptor.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; +using Orchard.AuditTrail.Models; using Orchard.Localization; -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class AuditTrailCategoryDescriptor { public string Category { get; set; } public LocalizedString Name { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailContext.cs similarity index 91% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailContext.cs index 55e067024..30b1303c4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailContext.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailContext.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Orchard.Security; -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class AuditTrailContext { public AuditTrailContext() { EventData = new Dictionary(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCreateContext.cs similarity index 69% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCreateContext.cs index 7bf93afdb..9ea45f226 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailCreateContext.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailCreateContext.cs @@ -1,4 +1,4 @@ -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class AuditTrailCreateContext : AuditTrailContext { public string Comment { get; set; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs similarity index 88% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs index 4368f4f4a..7bfb11200 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventDescriptor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs @@ -1,6 +1,6 @@ using Orchard.Localization; -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class AuditTrailEventDescriptor { public AuditTrailCategoryDescriptor CategoryDescriptor { get; set; } public string Event { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailFilterParameters.cs similarity index 60% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailFilterParameters.cs index dae826587..c75102343 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailFilterParameters.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailFilterParameters.cs @@ -1,9 +1,9 @@ using System; +using Orchard.AuditTrail.Models; -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class AuditTrailFilterParameters { - public string FilterKey { get; set; } - public string FilterValue { get; set; } + public Filters Filters { get; set; } public string UserName { get; set; } public DateTime? From { get; set; } public DateTime? To { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailOrderBy.cs similarity index 53% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailOrderBy.cs index f72899256..ccd577db5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailOrderBy.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailOrderBy.cs @@ -1,6 +1,7 @@ -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public enum AuditTrailOrderBy { DateDescending, + CategoryAscending, EventAscending } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeContext.cs new file mode 100644 index 000000000..c5344824d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeContext.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Localization; + +namespace Orchard.AuditTrail.Services.Models { + public class DescribeContext { + private readonly IDictionary _describes = new Dictionary(); + private readonly IList> _queryFilters = new List>(); + private readonly IList> _filterDisplays = new List>(); + + public IEnumerable> QueryFilters { + get { return _queryFilters; } + } + + public IEnumerable> FilterDisplays { + get { return _filterDisplays; } + } + + public IEnumerable Describe() { + var query = + from d in _describes.Values + select new AuditTrailCategoryDescriptor { + Category = d.Category, + Name = d.Name, + Events = d.Events + }; + + return query.ToArray(); + } + + public DescribeFor For(string category, LocalizedString name) { + DescribeFor describeFor; + if (!_describes.TryGetValue(category, out describeFor)) { + describeFor = new DescribeFor(category, name); + _describes[category] = describeFor; + } + return describeFor; + } + + public DescribeContext QueryFilter(Action queryAction) { + _queryFilters.Add(queryAction); + return this; + } + + public DescribeContext DisplayFilter(Action displayFilter) { + _filterDisplays.Add(displayFilter); + return this; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs similarity index 94% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs index 2f0dd3c23..81a7e7fa7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/DescribeFor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; using Orchard.AuditTrail.Helpers; -using Orchard.AuditTrail.Services; using Orchard.Localization; -namespace Orchard.AuditTrail.Models { +namespace Orchard.AuditTrail.Services.Models { public class DescribeFor { private readonly IList _events = new List(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs new file mode 100644 index 000000000..7f463d7eb --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs @@ -0,0 +1,15 @@ +using Orchard.DisplayManagement; + +namespace Orchard.AuditTrail.Services.Models { + public class DisplayFilterContext { + public DisplayFilterContext(IShapeFactory shapeFactory, Filters filters, dynamic filterLayout) { + ShapeFactory = shapeFactory; + Filters = filters; + FilterLayout = filterLayout; + } + + public dynamic ShapeFactory { get; set; } + public Filters Filters { get; set; } + public dynamic FilterLayout { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs new file mode 100644 index 000000000..06ec9007a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Collections.Specialized; + +namespace Orchard.AuditTrail.Services.Models { + public class Filters : Dictionary { + public static Filters From(NameValueCollection nameValues) { + var filters = new Filters(); + + foreach (string nameValue in nameValues) { + filters.Add(nameValue, nameValues[nameValue]); + } + + return filters; + } + + public Filters AddFilter(string key, string value) { + Add(key, value); + return this; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/QueryFilterContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/QueryFilterContext.cs new file mode 100644 index 000000000..434e254dc --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/QueryFilterContext.cs @@ -0,0 +1,14 @@ +using System.Linq; +using Orchard.AuditTrail.Models; + +namespace Orchard.AuditTrail.Services.Models { + public class QueryFilterContext { + public QueryFilterContext(IQueryable query, Filters filters) { + Query = query; + Filters = filters; + } + + public IQueryable Query { get; set; } + public Filters Filters { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs new file mode 100644 index 000000000..6f6a085a8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs @@ -0,0 +1,32 @@ +using System.IO; +using Orchard.DisplayManagement; + +namespace Orchard.AuditTrail.Shapes { + public class AuditTrailShapes : IDependency { + [Shape] + public void AuditTrailFilters(dynamic Shape, dynamic Display, TextWriter Output) { + DispayChildren(Shape, Display, Output); + } + + [Shape] + public void AuditTrailFilters_TripleFirst(dynamic Shape, dynamic Display, TextWriter Output) { + DispayChildren(Shape, Display, Output); + } + + [Shape] + public void AuditTrailFilters_TripleSecond(dynamic Shape, dynamic Display, TextWriter Output) { + DispayChildren(Shape, Display, Output); + } + + [Shape] + public void AuditTrailFilters_TripleThird(dynamic Shape, dynamic Display, TextWriter Output) { + DispayChildren(Shape, Display, Output); + } + + private void DispayChildren(dynamic shape, dynamic display, TextWriter output) { + foreach (var child in shape) { + output.Write(display(child)); + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css index 5a5d66a72..364962816 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -2,6 +2,16 @@ margin-bottom: 1em; } + .audit-trail-filter fieldset label { + display: inline-block; + width: 10em; + } + + .audit-trail-filter fieldset label.inline { + display: inline; + width: auto; + } + .audit-trail-list .info { line-height: 25px; } @@ -20,4 +30,4 @@ .audit-trail-site-settings table th.event-enabled { width: 60px; -} \ No newline at end of file +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css new file mode 100644 index 000000000..eae79aeb2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css @@ -0,0 +1,285 @@ +.table, .row, .cell { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + + .table > .row { + width: 100%; + } + + .table.fixed > .row { + margin-left: auto; + margin-right: auto; + } + +.row { + display: block; + margin: 0 0 20px 0; +} + + .row:after { + content: ""; + display: table; + clear: both; + } + +.cell { + display: block; + float: left; + padding-right: 10px; + padding-left: 10px; +} + +.row > .cell:last-of-type { + padding-right: 0; +} + +.row > .cell:first-of-type { + padding-left: 0; +} + +/* Opt-in outside padding */ +.row-pad { + padding: 20px 0 20px 20px; +} + + .row-pad .cell:last-of-type { + padding-right: 20px; + } + +.span-1-1 { + width: 100%; +} + +.span-1-2 { + width: 50%; +} + +.span-1-3 { + width: 33.33%; +} + +.span-1-4 { + width: 25%; +} + +.span-1-5 { + width: 20%; +} + +.span-1-6 { + width: 16.66%; +} + +.span-1-7 { + width: 14.28%; +} + +.span-1-8 { + width: 12.5%; +} + +.span-1-9 { + width: 11.11%; +} + +.span-1-10 { + width: 10%; +} + +.span-1-11 { + width: 9.09%; +} + +.span-1-12 { + width: 8.33%; +} + +.span-2-3 { + width: 66.66%; +} + +.span-2-4 { + width: 50%; +} + +.span-2-5 { + width: 40%; +} + +.span-2-6 { + width: 33.33%; +} + +.span-2-8 { + width: 25%; +} + +.span-2-10 { + width: 20%; +} + +.span-2-12 { + width: 16.66%; +} + +.span-3-4 { + width: 75%; +} + +.span-3-5 { + width: 60%; +} + +.span-3-6 { + width: 50%; +} + +.span-3-8 { + width: 37.5%; +} + +.span-3-10 { + width: 33.33%; +} + +.span-3-12 { + width: 25%; +} + +.span-4-5 { + width: 80%; +} + +.span-4-6 { + width: 66.66%; +} + +.span-4-8 { + width: 50%; +} + +.span-4-10 { + width: 40%; +} + +.span-4-12 { + width: 33.33%; +} + +.span-5-6 { + width: 83.33%; +} + +.span-5-8 { + width: 75%; +} + +.span-5-10 { + width: 50%; +} + +.span-5-12 { + width: 41.66%; +} + +.span-6-8 { + width: 75%; +} + +.span-6-10 { + width: 60%; +} + +.span-6-12 { + width: 50%; +} + +.span-7-8 { + width: 87.5%; +} + +.span-7-10 { + width: 70%; +} + +.span-7-12 { + width: 58.33%; +} + +.span-8-10 { + width: 80%; +} + +.span-8-12 { + width: 66.66%; +} + +.span-9-10 { + width: 90%; +} + +.span-9-12 { + width: 75%; +} + +.span-10-12 { + width: 83.33%; +} + +.span-11-12 { + width: 91.66%; +} + +/* Bootstrap compatible spans */ +.span-1 { width: 8.33%; } +.span-2 { width: 16.66%; } +.span-3 { width: 25%; } +.span-4 { width: 33.33%; } +.span-5 { width: 41.66%; } +.span-6 { width: 50%; } +.span-7 { width: 58.33%; } +.span-8 { width: 66.66%; } +.span-9 { width: 75%; } +.span-10 { width: 83.33%; } +.span-11 { width: 91.66%; } +.span-12 { width: 100%; } + + +/* RESPONSIVENESS */ + +/* Large desktop */ +@media (min-width: 1200px) { + .table.fixed > .row { + width: 1170px; + } +} + +/* Default */ +@media (min-width: 980px) and (max-width: 1199px) { + .table.fixed > .row { + width: 960px; + } +} + +/* Portrait tablet to landscape and desktop */ +@media (min-width: 768px) and (max-width: 979px) { + .table.fixed > .row { + width: 724px; + } +} + +/* Landscape phone to portrait tablet */ +@media (max-width: 767px) { + .table.fixed > .row { + width: 100%; + } +} + +/* Landscape phones and down */ +@media (max-width: 480px) { + .table.fixed > .row { + width: 100%; + } +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs index a794234cb..519819552 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailDetailsViewModel.cs @@ -1,4 +1,5 @@ using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailDetailsViewModel { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs index 8048a3624..3b9b5d2cb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSummaryViewModel.cs @@ -1,4 +1,5 @@ using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailEventSummaryViewModel { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs index a2d313754..dfbdac2e1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs @@ -1,12 +1,10 @@ using System.Collections.Generic; +using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailViewModel { - public AuditTrailViewModel() { - Filter = new AuditTrailFilterViewModel(); - } - - public AuditTrailFilterViewModel Filter { get; set; } + public dynamic FilterLayout { get; set; } + public AuditTrailOrderBy OrderBy { get; set; } public IEnumerable Records { get; set; } public dynamic List { get; set; } public dynamic Pager { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/CommonAuditTrailFilterViewModel.cs similarity index 52% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/CommonAuditTrailFilterViewModel.cs index bb3fcd95a..9a6d175ad 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailFilterViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/CommonAuditTrailFilterViewModel.cs @@ -1,17 +1,14 @@ -using Orchard.AuditTrail.Models; -using Orchard.Core.Common.ViewModels; +using Orchard.Core.Common.ViewModels; namespace Orchard.AuditTrail.ViewModels { - public class AuditTrailFilterViewModel { - public AuditTrailFilterViewModel() { + public class CommonAuditTrailFilterViewModel { + public CommonAuditTrailFilterViewModel() { From = new DateTimeEditor { ShowDate = true, ShowTime = false}; To = new DateTimeEditor { ShowDate = true, ShowTime = false }; } - public string FilterKey { get; set; } - public string FilterValue { get; set; } + public string UserName { get; set; } public DateTimeEditor From { get; set; } public DateTimeEditor To { get; set; } - public AuditTrailOrderBy OrderBy { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index d69f6f5a2..6fb0cacb4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -1,36 +1,47 @@ -@using Orchard.AuditTrail.Models +@using Orchard.AuditTrail.Services.Models @model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ + Style.Include("custom-grid.css"); Style.Include("admin.css"); - var from = Model.Filter.From; - var to = Model.Filter.To; - var orderBy = Model.Filter.OrderBy; + var orderBy = Model.OrderBy; var orderByItems = new List { - new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.DateDescending}, - new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.Filter.OrderBy == AuditTrailOrderBy.EventAscending}, + new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, + new SelectListItem {Text = T("Category (asc)").Text, Value = AuditTrailOrderBy.CategoryAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.CategoryAscending}, + new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.EventAscending}, }; Layout.Title = T("Audit Trail"); }
@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { -
- @Html.Hidden("filterkey", Model.Filter.FilterKey) - @Html.Hidden("filtervalue", Model.Filter.FilterValue) - @Html.Label("username", T("User:").Text) - @Html.TextBox("username", Model.Filter.UserName, new { @class = "text" }) - @Html.LabelFor(m => from, T("From:")) - @Html.EditorFor(m => from) - @Html.LabelFor(m => to, T("To:")) - @Html.EditorFor(m => to) - @Html.LabelFor(m => orderBy, T("Ordered by:")) - @Html.DropDownListFor(m => orderBy, orderByItems) - -
+
+
+
+ @Display(Model.FilterLayout) +
+
+
+
+ @Display(Model.FilterLayout.TripleFirst) +
+ @Html.LabelFor(m => orderBy, T("Ordered by:")) + @Html.DropDownListFor(m => orderBy, orderByItems) +
+
+
+ @Display(Model.FilterLayout.TripleSecond) +
+
+ @Display(Model.FilterLayout.TripleThird) +
+
+
+
+ +
+
+
} -
@if (!Model.Records.Any()) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml new file mode 100644 index 000000000..4a908da34 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml @@ -0,0 +1,11 @@ +@using Orchard.Core.Common.ViewModels +@{ + var from = (DateTimeEditor)Model.From; + var to = (DateTimeEditor)Model.To; +} +
+ @Html.Label("from.Date", T("From:").Text) + @Html.EditorFor(m => from) + @Html.Label("to.Date", T("To:").Text, new { @class = "inline" }) + @Html.EditorFor(m => to) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml new file mode 100644 index 000000000..e36a07db8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml @@ -0,0 +1,4 @@ +
+ @Html.Label("username", T("User:").Text) + @Html.TextBox("username", (string)Model.UserName, new { @class = "text" }) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml new file mode 100644 index 000000000..b4d11d460 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml @@ -0,0 +1,11 @@ +@using Orchard.ContentManagement +@{ + var contentItem = (ContentItem)Model.ContentItem; +} +@if (contentItem != null) { +
+ @Html.Label("contentitem", T("Content Item:").Text) + @Html.ItemEditLink(contentItem) + @Html.Hidden("content", contentItem.Id) +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml new file mode 100644 index 000000000..74fe52719 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml @@ -0,0 +1,10 @@ +@using Orchard.ContentManagement.MetaData.Models +@{ + var contentTypes = (IList) Model.ContentTypes; + var currentContentType = (string)Model.ContentType; + var listItems = contentTypes.Select(x => new SelectListItem {Text = x.DisplayName, Value = x.Name, Selected = x.Name == currentContentType}); +} +
+ @Html.Label("contenttype", T("Content Type:").Text) + @Html.DropDownList("contenttype", listItems, "") +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index ed01c5791..b1f908713 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -11,7 +11,7 @@ @foreach (var category in Model.Categories) {
@category.Name - + @@ -25,12 +25,12 @@ var checkboxId = String.Format("Event{0}{1}", i, j); j++; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml index d7549045c..c161ea8c9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml @@ -3,6 +3,6 @@ } @if (contentId > 0) {
- @Html.ActionLink(T("View Audit Trail").Text, "Index", "Admin", new { filterkey = "content", filtervalue = contentId, area = "Orchard.AuditTrail" }, null) + @Html.ActionLink(T("View Audit Trail").Text, "Index", "Admin", new { content = contentId, area = "Orchard.AuditTrail" }, null)
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index 113ff6f63..edf252388 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -48,7 +48,7 @@ diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml index 54d6dc060..0e7112d90 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.Contents.AuditTrail.SummaryAdmin.cshtml @@ -1 +1 @@ -@T("Audit Trail")@T(" | ") \ No newline at end of file +@T("Audit Trail")@T(" | ") \ No newline at end of file From 7787ce91382a76b1ccf8ffa486a5f9617617989f Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 16:43:02 -0700 Subject: [PATCH 038/116] 154: Added category filter. --- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 1 + .../Services/CommonAuditTrailEventHandler.cs | 11 +++++++++-- .../Views/AuditTrailFilter-Common-Category.cshtml | 10 ++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 471b08fcc..102f14b0e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -133,6 +133,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs index 2e2ec0b7b..e43c734ae 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs @@ -16,17 +16,19 @@ namespace Orchard.AuditTrail.Services { } public override void Filter(QueryFilterContext context) { - // Common filters (username, from and to). + // Common filters (username, from and to, category). var userName = context.Filters.Get("username"); var fromDate = context.Filters.Get("from.Date"); var fromTime = context.Filters.Get("from.Time"); var toDate = context.Filters.Get("to.Date"); var toTime = context.Filters.Get("to.Time"); + var category = context.Filters.Get("category"); var from = _dateServices.ConvertFromLocalString(fromDate, fromTime).Earliest(); var to = _dateServices.ConvertFromLocalString(toDate, toTime).Latest(); var query = context.Query; if (!String.IsNullOrWhiteSpace(userName)) query = query.Where(x => x.UserName == userName); + if (!String.IsNullOrWhiteSpace(category)) query = query.Where(x => x.Category == category); if (from != null) query = query.Where(x => x.CreatedUtc >= from); if (to != null) query = query.Where(x => x.CreatedUtc <= to); @@ -34,16 +36,21 @@ namespace Orchard.AuditTrail.Services { } public override void DisplayFilter(DisplayFilterContext context) { - // Common filters (username, from and to). + // Common filters (username, from and to, category). var userName = context.Filters.Get("username"); var fromDate = context.Filters.Get("from.Date"); var toDate = context.Filters.Get("to.Date"); + var category = context.Filters.Get("category"); var userNameFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__User(UserName: userName); var dateFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Date( From: new DateTimeEditor {Date = fromDate, ShowDate = true}, To: new DateTimeEditor {Date = toDate, ShowDate = true}); + var categoryFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Category( + Categories: _auditTrailManager.Value.DescribeCategories().ToArray(), + Category: category); context.FilterLayout.TripleFirst.Add(dateFilterDisplay); + context.FilterLayout.TripleFirst.Add(categoryFilterDisplay); context.FilterLayout.TripleSecond.Add(userNameFilterDisplay); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml new file mode 100644 index 000000000..8a304ae91 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Services.Models +@{ + var categories = (IList)Model.Categories; + var currentCategory = (string)Model.Category; + var listItems = categories.Select(x => new SelectListItem { Text = x.Name.Text, Value = x.Category, Selected = x.Category == currentCategory }); +} +
+ @Html.Label("category", T("Category:").Text) + @Html.DropDownList("category", listItems, "") +
\ No newline at end of file From 4588d906d754e95d73890b7769dc62d550bb6536 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 17:13:53 -0700 Subject: [PATCH 039/116] 148: Added "enable all" checkbox to each category. --- .../Scripts/audit-trail-admin.js | 48 ++++++++++++++++--- .../Parts.AuditTrailSettings.cshtml | 12 ++++- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js index 0b8b47007..acd8577a1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js @@ -1,10 +1,44 @@ (function($) { - // Initialize Expando control - $(".expando-wrapper legend").expandoControl( - function (controller) { - return controller.nextAll(".expando"); - }, { - collapse: true, - remember: true + + var initExpandoControl = function() { + // Initialize Expando control + $(".expando-wrapper legend").expandoControl( + function(controller) { + return controller.nextAll(".expando"); + }, { + collapse: true, + remember: true + }); + }; + + var initCheckAll = function() { + // Check all / uncheck all. + $("table.check-all").each(function() { + var table = $(this); + var controller = table.find("thead input[type=\"checkbox\"]"); + var checkboxes = table.find("tbody input[type=\"checkbox\"]"); + + var updateController = function () { + var allChecked = checkboxes.filter(":not(:checked)").length == 0; + controller.prop("checked", allChecked); + } + + table.on("change", "thead input[type=\"checkbox\"]", function() { + var isChecked = $(this).is(":checked"); + checkboxes.prop("checked", isChecked); + }); + + table.on("change", "tbody input[type=\"checkbox\"]", function () { + updateController(); + }); + + updateController(); }); + }; + + $(function() { + initExpandoControl(); + initCheckAll(); + }); + })(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index b1f908713..afc62e66a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -1,6 +1,9 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailSettingsViewModel @{ Style.Include("admin.css"); + Script.Require("ShapesBase"); + Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); + Script.Include("audit-trail-admin.js").AtFoot(); }
@@ -12,12 +15,17 @@
@category.Name -
- + @evnt.Name @evnt.Description - checked="checked"} /> + checked="checked"} />
- @Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { filterKey = "content", filterValue = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null) + @Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { content = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null)
+
- + @{ var j = 0; } From bb341d12611425dc354eeea133fe4ebae1063313 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 17:28:01 -0700 Subject: [PATCH 040/116] 150: Cleaning up content event details view and adding more information. --- .../Views/AuditTrailEvent-Content.cshtml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index b70cf9496..365b4d52c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -1,21 +1,21 @@ -@using Orchard.AuditTrail.Providers.Content +@using Orchard.AuditTrail.Models +@using Orchard.AuditTrail.Providers.Content @using Orchard.ContentManagement @{ + var record = (AuditTrailEventRecord)Model.Record; var contentItem = (ContentItem) Model.ContentItem; var previousVersion = (ContentItem) Model.PreviousVersion; var diffNodes = (IEnumerable) Model.DiffNodes; } -
- @T("This version:") - @Html.ItemEditLink(contentItem) -
+
+ @Html.ItemDisplayText(contentItem)@T(" - ")@contentItem.ContentType + @T("Version {0}", contentItem.Version) + @if (!String.IsNullOrWhiteSpace(record.Comment)) { + "@record.Comment" + } +
@if (previousVersion != null) { -
- @T("Previous version:") - @Html.ItemEditLink(previousVersion) -
-
@T("Event") @T("Description")@T("Enabled") + +
From abc9acf2e1fd9a34119da3122f4878ea9ad35c64 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 17:57:54 -0700 Subject: [PATCH 041/116] 146: Added custom controller for read-only view of content. --- .../Controllers/AdminController.cs | 4 +-- .../Controllers/ContentController.cs | 26 ++++++++++++++++++ .../Orchard.AuditTrail.csproj | 3 ++ .../Scripts/audit-trail-admin.js | 9 ++++-- .../Orchard.AuditTrail/Styles/admin.css | 19 +++++++++++++ .../Orchard.AuditTrail/Styles/overlay.png | Bin 0 -> 1146 bytes ...uditTrailEvent-Content.SummaryAdmin.cshtml | 2 +- .../Views/Content/Detail.cshtml | 14 ++++++++++ .../Views/Parts.AuditTrail.Link.cshtml | 2 +- .../Views/Parts.AuditTrail.cshtml | 2 +- 10 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index bf69ac027..5c8e4176a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -1,7 +1,5 @@ -using System; -using System.Linq; +using System.Linq; using System.Web.Mvc; -using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.ViewModels; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs new file mode 100644 index 000000000..c3dfcf16f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs @@ -0,0 +1,26 @@ +using System.Web.Mvc; +using Orchard.ContentManagement; +using Orchard.Security; +using Orchard.UI.Admin; + +namespace Orchard.AuditTrail.Controllers { + [Admin] + public class ContentController : Controller { + private readonly IAuthorizer _authorizer; + private readonly IContentManager _contentManager; + + public ContentController(IAuthorizer authorizer, IContentManager contentManager) { + _authorizer = authorizer; + _contentManager = contentManager; + } + + public ActionResult Detail(int id, int version) { + var contentItem = _contentManager.Get(id, VersionOptions.Number(version)); + if (!_authorizer.Authorize(Core.Contents.Permissions.ViewContent, contentItem)) + return new HttpUnauthorizedResult(); + + var editor = _contentManager.BuildEditor(contentItem); + return View(editor); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 102f14b0e..35e370313 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -83,6 +83,7 @@ + @@ -134,6 +135,7 @@ + @@ -151,6 +153,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js index acd8577a1..e33cd27ba 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js @@ -1,7 +1,6 @@ (function($) { var initExpandoControl = function() { - // Initialize Expando control $(".expando-wrapper legend").expandoControl( function(controller) { return controller.nextAll(".expando"); @@ -12,7 +11,6 @@ }; var initCheckAll = function() { - // Check all / uncheck all. $("table.check-all").each(function() { var table = $(this); var controller = table.find("thead input[type=\"checkbox\"]"); @@ -36,9 +34,16 @@ }); }; + var disableContentEditor = function () { + $(".content-disabled input").prop("disabled", true); + $(".content-disabled textarea").prop("disabled", true); + $(".content-disabled button").prop("disabled", true); + }; + $(function() { initExpandoControl(); initCheckAll(); + disableContentEditor(); }); })(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css index 364962816..0a9638f24 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css @@ -31,3 +31,22 @@ .audit-trail-site-settings table th.event-enabled { width: 60px; } + +.content-disabled { + position: relative; +} + +.content-disabled .overlay { + position: absolute; + left: -24px; + top: -16px; + right: -24px; + bottom: -28px; + background: url('overlay.png'); +} + +.content-disabled .edit-item-secondary, +.content-disabled .audit-trail.expando-wrapper, +.content-disabled .audit-trail-link { + display: none; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..9524f28bc549a0a8a1a743894885e24e67aa97a7 GIT binary patch literal 1146 zcmc&zKX21O6u+ucRaFfG5)v>S?gE1Nd`_I$R^2ML6B>y`RT|N3)Uhv()!Jw5D|S1T zKMN9{g#ku}Msz}KjC=tWP`?03oYSOb2wfO>l707{-tWEN`*W{1+Ybv%x0e6_h31Cc z;pcJwEiUl?>6-JIAGcV&$F}HzrA|yh&7*w+n}M@SI>hk~pMD~%0LlUTAR?KF@cJx6kSQiu&RkzDQg%% zfU<;32un!TiWuwVs*WpgA_C7Adjq{=Hzv8bW(Y&ZA|0VLO~te%(s&nPP1BGhBUvtT zk79BdGAApB$;vc>O%gZuBj(c(<`JDfJz$2wnVy#rM6K3E;4qmqink19PK2;1p&-cX z8hajtyJqaw<*dL+YA%tgf5w4{Yz}^N~~_h#9=hCe*M}F Oz@=Gl+i%UC7rz1ckV2IJ literal 0 HcmV?d00001 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index d2ac1a9bb..cfd469ee6 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -8,5 +8,5 @@
@T("version {0}", contentItemVersionNumber)@T(" - ") - @title + @title
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml new file mode 100644 index 000000000..4987192f0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml @@ -0,0 +1,14 @@ +@using Orchard.ContentManagement +@{ + Style.Include("admin.css"); + Script.Require("ShapesBase"); + Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); + Script.Include("audit-trail-admin.js").AtFoot(); + + var contentItem = (ContentItem)Model.ContentItem; + Layout.Title = T("{0} - (version {1})", contentItem.ContentType, contentItem.Version); +} +
+ @Display(Model) +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml index c161ea8c9..74159cfeb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.Link.cshtml @@ -2,7 +2,7 @@ var contentId = (int)Model.ContentPart.Id; } @if (contentId > 0) { -
+ } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index edf252388..dee36c96b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -11,7 +11,7 @@ } @if (auditTrailPart.Id > 0) { -
+
@T("Audit Trail")
From 7a8765811beb880ec72bbe4c62ef516386ec40fa Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 19:27:26 -0700 Subject: [PATCH 042/116] Added audit trail settings event provider. --- .../Handlers/AuditTrailSettingsPartHandler.cs | 27 ++++++++++++- .../AuditTrailTrimmingSettingsPartHandler.cs | 39 ++++++++++++++++--- .../Helpers/EventDataHelper.cs | 2 +- .../Orchard.AuditTrail.csproj | 7 +++- .../SettingsAuditTrailEventProvider.cs | 14 +++++++ ...TrimmingSettingsAuditTrailEventProvider.cs | 16 ++++++++ .../Providers/Content/GlobalContentHandler.cs | 8 +++- .../IAuditTrailSettingsEventHandler.cs | 8 ++++ .../Models/AuditTrailSettingsContext.cs | 3 ++ .../Views/Admin/Detail.cshtml | 4 +- ...ailSettings-TrimmingSettingsChanged.cshtml | 10 +++++ ... => AuditTrailEvent-Content - Copy.cshtml} | 0 12 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailSettingsEventHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailSettingsContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/{AuditTrailEvent-Content.cshtml => AuditTrailEvent-Content - Copy.cshtml} (100%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs index 8a34f02d2..33306c224 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Providers.AuditTrail; +using Orchard.AuditTrail.Services; using Orchard.Caching; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -12,11 +14,18 @@ using Orchard.Logging; namespace Orchard.AuditTrail.Handlers { public class AuditTrailSettingsPartHandler : ContentHandler { private readonly ISignals _signals; + private string _oldEventSettings; + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; - public AuditTrailSettingsPartHandler(ISignals signals) { + public AuditTrailSettingsPartHandler(ISignals signals, IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { _signals = signals; + _auditTrailManager = auditTrailManager; + _wca = wca; Filters.Add(new ActivatingFilter("Site")); OnActivated(SetupLazyFields); + OnUpdating(BeginUpdateEvent); + OnUpdated(EndUpdateEvent); OnGetContentItemMetadata(GetMetadata); T = NullLocalizer.Instance; } @@ -36,6 +45,22 @@ namespace Orchard.AuditTrail.Handlers { }); } + private void BeginUpdateEvent(UpdateContentContext context, AuditTrailSettingsPart part) { + _oldEventSettings = part.Retrieve("Events"); + } + + private void EndUpdateEvent(UpdateContentContext context, AuditTrailSettingsPart part) { + var newEventSettings = part.Retrieve("Events"); + + if (newEventSettings == _oldEventSettings) + return; + + _auditTrailManager.CreateRecord( + eventName: SettingsAuditTrailEventProvider.EventsChanged, + user: _wca.GetContext().CurrentUser); + } + + private IEnumerable DeserializeProviderConfiguration(string data) { if (String.IsNullOrWhiteSpace(data)) return Enumerable.Empty(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs index 7bee7cc4e..018943fdf 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs @@ -1,4 +1,7 @@ -using Orchard.AuditTrail.Models; +using System.Collections.Generic; +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Providers.AuditTrail; +using Orchard.AuditTrail.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.Environment.Extensions; @@ -7,17 +10,43 @@ using Orchard.Localization; namespace Orchard.AuditTrail.Handlers { [OrchardFeature("Orchard.AuditTrail.Trimming")] public class AuditTrailTrimmingSettingsPartHandler : ContentHandler { - - public AuditTrailTrimmingSettingsPartHandler() { + private int _oldThreshold; + private readonly IAuditTrailManager _auditTrailManager; + private readonly IWorkContextAccessor _wca; + + public AuditTrailTrimmingSettingsPartHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { + _auditTrailManager = auditTrailManager; + _wca = wca; Filters.Add(new ActivatingFilter("Site")); - OnGetContentItemMetadata(GetMetadata); + OnGetContentItemMetadata(GetMetadata); + OnUpdating(BeginUpdateEvent); + OnUpdated(EndUpdateEvent); T = NullLocalizer.Instance; } public Localizer T { get; set; } - private void GetMetadata(GetContentItemMetadataContext context, AuditTrailSettingsPart part) { + private void GetMetadata(GetContentItemMetadataContext context, AuditTrailTrimmingSettingsPart part) { context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Audit Trail"))); } + + private void BeginUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { + _oldThreshold = part.Threshold; + } + + private void EndUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { + var newThreshold = part.Threshold; + + if (newThreshold == _oldThreshold) + return; + + _auditTrailManager.CreateRecord( + eventName: TrimmingSettingsAuditTrailEventProvider.TrimmingSettingsChanged, + user: _wca.GetContext().CurrentUser, + eventData: new Dictionary { + {"OldThreshold", _oldThreshold}, + {"NewThreshold", newThreshold} + }); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs index 1b0e00807..664af226a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace Orchard.AuditTrail.Helpers { public static class EventDataHelper { public static T Get(this IDictionary eventData, string key) { - if (!eventData.ContainsKey(key)) + if (eventData == null || !eventData.ContainsKey(key)) return default(T); var value = eventData[key]; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 35e370313..757fe2f77 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -136,6 +136,7 @@ + @@ -166,8 +167,12 @@ + + + + @@ -247,7 +252,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs new file mode 100644 index 000000000..c77d6b6b3 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs @@ -0,0 +1,14 @@ +using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; + +namespace Orchard.AuditTrail.Providers.AuditTrail { + public class SettingsAuditTrailEventProvider : AuditTrailEventProviderBase { + + public const string EventsChanged = "EventsChanged"; + + public override void Describe(DescribeContext context) { + context.For("AuditTrailSettings", T("Audit Trail Settings")) + .Event(this, EventsChanged, T("Events Changed"), T("Audit Trail event settings were changed."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs new file mode 100644 index 000000000..6f2ce0884 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs @@ -0,0 +1,16 @@ +using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; +using Orchard.Environment.Extensions; + +namespace Orchard.AuditTrail.Providers.AuditTrail { + [OrchardFeature("Orchard.AuditTrail.Trimming")] + public class TrimmingSettingsAuditTrailEventProvider : AuditTrailEventProviderBase { + + public const string TrimmingSettingsChanged = "TrimmingSettingsChanged"; + + public override void Describe(DescribeContext context) { + context.For("AuditTrailSettings", T("Audit Trail Settings")) + .Event(this, TrimmingSettingsChanged, T("Trimming Settings Changed"), T("Audit Trail trimming settings were changed."), enableByDefault: true); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 99c94ee66..d49207b67 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Globalization; +using System.Linq; using Orchard.AuditTrail.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -39,6 +40,11 @@ namespace Orchard.AuditTrail.Providers.Content { } private void RecordAuditTrailEvent(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { + var blackList = new[] {"Site"}; + + if (blackList.Contains(content.ContentItem.ContentType)) + return; + var title = _contentManager.GetItemMetadata(content).DisplayText; var properties = new Dictionary { @@ -58,7 +64,7 @@ namespace Orchard.AuditTrail.Providers.Content { _auditTrailManager.CreateRecord( eventName, - _wca.GetContext().CurrentUser, + _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "content", diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailSettingsEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailSettingsEventHandler.cs new file mode 100644 index 000000000..d25cf19f2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailSettingsEventHandler.cs @@ -0,0 +1,8 @@ +using Orchard.AuditTrail.Services.Models; +using Orchard.Events; + +namespace Orchard.AuditTrail.Services { + public interface IAuditTrailSettingsEventHandler : IEventHandler { + void Updated(AuditTrailSettingsContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailSettingsContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailSettingsContext.cs new file mode 100644 index 000000000..c285b0275 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailSettingsContext.cs @@ -0,0 +1,3 @@ +namespace Orchard.AuditTrail.Services.Models { + public class AuditTrailSettingsContext {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml index e3d76fbc1..3b06415e9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml @@ -10,9 +10,9 @@
@descriptor.Name - @descriptor.CategoryDescriptor.Name
- @Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g")) + @T("On: {0}", Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g"))) @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@record.UserName + @T(" | ")@T("By: {0}", record.UserName) }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml new file mode 100644 index 000000000..00249f063 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary)Model.EventData; + var oldThreshold = eventData.Get("OldThreshold"); + var newThreshold = eventData.Get("NewThreshold"); +} + +
+ @T("Trimming threshold changed from {0} to {1}", oldThreshold, newThreshold) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content - Copy.cshtml similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content - Copy.cshtml From 1dc4837c69ff7acc5df3ad7e7f0061c8cc113d16 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 19:38:06 -0700 Subject: [PATCH 043/116] 161: Implemented "mandatory" events. --- .../Drivers/AuditTrailSettingsPartDriver.cs | 7 ++++--- .../AuditTrail/SettingsAuditTrailEventProvider.cs | 2 +- .../Orchard.AuditTrail/Scripts/audit-trail-admin.js | 2 +- .../Orchard.AuditTrail/Services/AuditTrailManager.cs | 3 +++ .../Services/Models/AuditTrailEventDescriptor.cs | 5 +++++ .../Services/Models/DescribeFor.cs | 12 ++++++++++-- .../ViewModels/AuditTrailEventSettingsViewModel.cs | 1 + .../EditorTemplates/Parts.AuditTrailSettings.cshtml | 2 +- 8 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index 1041a131a..b5a211314 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -39,13 +39,14 @@ namespace Orchard.AuditTrail.Drivers { Event = eventDescriptor.Event, Name = eventDescriptor.Name, Description = eventDescriptor.Description, - IsEnabled = eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault + IsEnabled = eventDescriptor.IsMandatory || (eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault), + IsMandatory = eventDescriptor.IsMandatory }).ToList() }).ToList() }; if (updater != null) { - if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { + if (updater.TryUpdateModel(viewModel, Prefix, new[] { "IsEnabled" }, null)) { foreach (var eventSettingViewModel in viewModel.Categories.SelectMany(x => x.Events)) { var eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventSettingViewModel.Event); @@ -54,7 +55,7 @@ namespace Orchard.AuditTrail.Drivers { eventSettings.Add(eventSetting); } - eventSetting.IsEnabled = eventSettingViewModel.IsEnabled; + eventSetting.IsEnabled = eventSettingViewModel.IsEnabled || eventSettingViewModel.IsMandatory; } part.EventSettings = eventSettings; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs index c77d6b6b3..deeab756c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs @@ -8,7 +8,7 @@ namespace Orchard.AuditTrail.Providers.AuditTrail { public override void Describe(DescribeContext context) { context.For("AuditTrailSettings", T("Audit Trail Settings")) - .Event(this, EventsChanged, T("Events Changed"), T("Audit Trail event settings were changed."), enableByDefault: true); + .Event(this, EventsChanged, T("Events Changed"), T("Audit Trail event settings were changed."), enableByDefault: true, isMandatory: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js index e33cd27ba..519fa06df 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js @@ -14,7 +14,7 @@ $("table.check-all").each(function() { var table = $(this); var controller = table.find("thead input[type=\"checkbox\"]"); - var checkboxes = table.find("tbody input[type=\"checkbox\"]"); + var checkboxes = table.find("tbody input[type=\"checkbox\"]:not(:disabled)"); var updateController = function () { var allChecked = checkboxes.filter(":not(:checked)").length == 0; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 1c384dc08..844324fbd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -160,6 +160,9 @@ namespace Orchard.AuditTrail.Services { } private bool IsEventEnabled(AuditTrailEventDescriptor eventDescriptor) { + if(eventDescriptor.IsMandatory) + return true; + var settingsDictionary = _cacheManager.Get("AuditTrail.EventSettings", context => { context.Monitor(_signals.When("AuditTrail.EventSettings")); return _siteService.GetSiteSettings().As().EventSettings.ToDictionary(x => x.EventName); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs index 7bfb11200..e5e83a3fb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs @@ -7,5 +7,10 @@ namespace Orchard.AuditTrail.Services.Models { public LocalizedString Name { get; set; } public LocalizedString Description { get; set; } public bool IsEnabledByDefault { get; set; } + + /// + /// Wether the event can be disabled or not. + /// + public bool IsMandatory { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs index 81a7e7fa7..7d360a0a9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs @@ -18,7 +18,14 @@ namespace Orchard.AuditTrail.Services.Models { public string Category { get; private set; } public LocalizedString Name { get; private set; } - public DescribeFor Event(IAuditTrailEventProvider provider, string eventName, LocalizedString name, LocalizedString description, bool enableByDefault = false) { + public DescribeFor Event( + IAuditTrailEventProvider provider, + string eventName, + LocalizedString name, + LocalizedString description, + bool enableByDefault = false, + bool isMandatory = false) { + _events.Add(new AuditTrailEventDescriptor { CategoryDescriptor = new AuditTrailCategoryDescriptor { Category = Category, @@ -28,7 +35,8 @@ namespace Orchard.AuditTrail.Services.Models { Event = EventNameHelper.GetFullyQualifiedEventName(provider.GetType(), eventName), Name = name, Description = description, - IsEnabledByDefault = enableByDefault + IsEnabledByDefault = enableByDefault, + IsMandatory = isMandatory }); return this; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs index ce652ced7..ff79dff28 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs @@ -7,5 +7,6 @@ namespace Orchard.AuditTrail.ViewModels { public LocalizedString Name { get; set; } public LocalizedString Description { get; set; } public bool IsEnabled { get; set; } + public bool IsMandatory { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index afc62e66a..f1051e37b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -38,7 +38,7 @@
j++; From 50bbb4ab24215fb92179270fd82cfa19eaaaa1dc Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 19:49:56 -0700 Subject: [PATCH 044/116] Created separate features for User, Role and Content Type Definition related event providers. --- .../Modules/Orchard.AuditTrail/Module.txt | 17 ++++++++++++++++- .../Orchard.AuditTrail.csproj | 5 ++++- .../ContentDefinitionEventHandler.cs | 12 ++++++++++++ .../ContentPartAuditTrailEventProvider.cs | 5 +++-- .../ContentTypeAuditTrailEventProvider.cs | 2 ++ .../GlobalContentDefinitionEditorEvents.cs | 2 ++ .../IContentDefinitionEventHandler.cs | 14 -------------- .../Role/RoleAuditTrailEventProvider.cs | 5 +++-- .../Providers/Role/RoleEventHandler.cs | 2 ++ .../User/UserAuditTrailEventProvider.cs | 5 +++-- .../Providers/User/UserEventHandler.cs | 2 ++ 11 files changed, 49 insertions(+), 22 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 72fb53bbf..ceccc1818 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -20,4 +20,19 @@ Features: Name: Audit Trail Trimming Description: Provides a background task that regularly deletes old audit trail records. Category: Security - Dependencies: Orchard.AuditTrail \ No newline at end of file + Dependencies: Orchard.AuditTrail + Orchard.AuditTrail.User: + Name: Audit Trail User Events + Description: Provides event providers for user related events. + Category: Security + Dependencies: Orchard.AuditTrail, Orchard.Users + Orchard.AuditTrail.Role: + Name: Audit Trail Role Events + Description: Provides event providers for role related events. + Category: Security + Dependencies: Orchard.AuditTrail, Orchard.Roles + Orchard.AuditTrail.ContentTypeDefinition: + Name: Audit Trail Content Type Definition Events + Description: Provides event providers for content type definition related events. + Category: Security + Dependencies: Orchard.AuditTrail, Orchard.ContentTypes \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 757fe2f77..cb1c4f668 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -147,6 +147,10 @@ {9916839C-39FC-4CEB-A5AF-89CA7E87119F} Orchard.Core + + {0e7646e8-fe8f-43c1-8799-d97860925ec4} + Orchard.ContentTypes + {fe5c5947-d2d5-42c5-992a-13d672946135} Orchard.ImportExport @@ -195,7 +199,6 @@ - diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs index c184f4596..91f473263 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs @@ -1,8 +1,11 @@ using System.Collections.Generic; using Orchard.AuditTrail.Services; using Orchard.ContentManagement.MetaData.Models; +using Orchard.ContentTypes.Events; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { + [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] public class ContentDefinitionEventHandler : IContentDefinitionEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; @@ -76,5 +79,14 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { }; _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); } + + public void ContentTypeCreated(ContentTypeCreatedContext context) {} + public void ContentTypeRemoved(ContentTypeRemovedContext context) {} + public void ContentPartCreated(ContentPartCreatedContext context) {} + public void ContentPartRemoved(ContentPartRemovedContext context) {} + public void ContentPartAttached(ContentPartAttachedContext context) {} + public void ContentPartDetached(ContentPartDetachedContext context) {} + public void ContentFieldAttached(ContentFieldAttachedContext context) {} + public void ContentFieldDetached(ContentFieldDetachedContext context) {} } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs index 52a4fae68..dff523597 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -1,8 +1,9 @@ -using Orchard.AuditTrail.Models; -using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { + [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] public class ContentPartAuditTrailEventProvider : AuditTrailEventProviderBase { public const string Created = "Created"; public const string Removed = "Removed"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 55537237b..bf29d6f30 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -4,8 +4,10 @@ using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; using Orchard.ContentManagement.MetaData; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { + [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] public class ContentTypeAuditTrailEventProvider : AuditTrailEventProviderBase { private readonly IContentDefinitionManager _contentDefinitionManager; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index f61106b3d..6a4c36573 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -4,8 +4,10 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Builders; using Orchard.ContentManagement.ViewModels; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { + [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] public class GlobalContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs deleted file mode 100644 index e5f921f7c..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/IContentDefinitionEventHandler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Orchard.Events; - -namespace Orchard.AuditTrail.Providers.ContentDefinition { - public interface IContentDefinitionEventHandler : IEventHandler { - void ContentTypeCreated(dynamic context); - void ContentTypeRemoved(dynamic context); - void ContentPartCreated(dynamic context); - void ContentPartRemoved(dynamic context); - void ContentPartAttached(dynamic context); - void ContentPartDetached(dynamic context); - void ContentFieldAttached(dynamic context); - void ContentFieldDetached(dynamic context); - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs index ebac1ea51..2c0c301e6 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs @@ -1,8 +1,9 @@ -using Orchard.AuditTrail.Models; -using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.Role { + [OrchardFeature("Orchard.AuditTrail.Role")] public class RoleAuditTrailEventProvider : AuditTrailEventProviderBase { public const string Created = "Created"; public const string Removed = "Removed"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs index 6da64a24d..e73562a78 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using Orchard.AuditTrail.Services; +using Orchard.Environment.Extensions; using Orchard.Security; namespace Orchard.AuditTrail.Providers.Role { + [OrchardFeature("Orchard.AuditTrail.Role")] public class RoleEventHandler : IRoleEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs index 38325709a..6bb5bb2d1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs @@ -1,8 +1,9 @@ -using Orchard.AuditTrail.Models; -using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; +using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.User { + [OrchardFeature("Orchard.AuditTrail.User")] public class UserAuditTrailEventProvider : AuditTrailEventProviderBase { public const string LoggedIn = "LoggedIn"; public const string LoggedOut = "LoggedOut"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs index 185f0d156..fe58eb41a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using Orchard.AuditTrail.Services; +using Orchard.Environment.Extensions; using Orchard.Security; namespace Orchard.AuditTrail.Providers.User { + [OrchardFeature("Orchard.AuditTrail.User")] public class UserEventHandler : IUserEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; From d8437d3435abd435a32dfc5c2ebd64c08f81ec3a Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 20:05:28 -0700 Subject: [PATCH 045/116] Storing EventData as XML instead of CData. --- .../ImportExport/AuditTrailExportHandler.cs | 33 ++++++++++++------- .../ImportExport/AuditTrailExportStep.cs | 1 - .../ImportExport/AuditTrailImportHandler.cs | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs index 8f735bb08..82b5cace9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Orchard.AuditTrail.Models; using Orchard.Data; using Orchard.Environment.Extensions; -using Orchard.Events; using Orchard.ImportExport.Services; namespace Orchard.AuditTrail.ImportExport { @@ -22,7 +20,7 @@ namespace Orchard.AuditTrail.ImportExport { public void Exported(ExportContext context) { - if (!((IEnumerable)context.ExportOptions.CustomSteps).Contains("AuditTrail")) { + if (!context.ExportOptions.CustomSteps.Contains("AuditTrail")) { return; } @@ -37,14 +35,14 @@ namespace Orchard.AuditTrail.ImportExport { foreach (var record in records) { root.Add(new XElement("Event", - new XAttribute("Name", record.Event), - new XAttribute("Category", record.Category), - new XAttribute("User", record.UserName), - new XAttribute("CreatedUtc", record.CreatedUtc), - new XAttribute("EventFilterKey", record.EventFilterKey), - new XAttribute("EventFilterData", record.EventFilterData), + CreateAttribute("Name", record.Event), + CreateAttribute("Category", record.Category), + CreateAttribute("User", record.UserName), + CreateAttribute("CreatedUtc", record.CreatedUtc), + CreateAttribute("EventFilterKey", record.EventFilterKey), + CreateAttribute("EventFilterData", record.EventFilterData), CreateElement("Comment", record.Comment), - CreateCDataElement("EventData", record.EventData))); + ParseEventData(record.EventData))); } } @@ -52,8 +50,19 @@ namespace Orchard.AuditTrail.ImportExport { return !String.IsNullOrWhiteSpace(value) ? new XElement(name, value) : null; } - private static XElement CreateCDataElement(string name, string value) { - return !String.IsNullOrWhiteSpace(value) ? new XElement(name, new XCData(value)) : null; + private static XAttribute CreateAttribute(string name, string value) { + return !String.IsNullOrWhiteSpace(value) ? new XAttribute(name, value) : null; + } + + private static XAttribute CreateAttribute(string name, object value) { + return new XAttribute(name, value); + } + + private static XElement ParseEventData(string eventData) { + if(String.IsNullOrWhiteSpace(eventData)) + return new XElement("EventData"); + + return XElement.Parse(eventData); } } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs index dc0291953..786f84529 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportStep.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Orchard.Environment.Extensions; -using Orchard.Events; using Orchard.ImportExport.Services; namespace Orchard.AuditTrail.ImportExport { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs index 9fffd5b05..9ad6af060 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs @@ -29,7 +29,7 @@ namespace Orchard.AuditTrail.ImportExport { EventFilterKey = eventElement.Attr("EventFilterKey"), EventFilterData = eventElement.Attr("EventFilterData"), Comment = eventElement.El("Comment"), - EventData = eventElement.El("EventData"), + EventData = eventElement.Element("EventData").ToString(), }; _auditTrailEventRepository.Create(record); From 43ad30c3fbe8662dadc9d678f270cccf192ad3ba Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 20:40:23 -0700 Subject: [PATCH 046/116] Added content identity to event data and performed some minor renaming. --- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 4 +++- .../Providers/Content/ContentAuditTrailEventShapes.cs | 4 ++-- .../Providers/Content/GlobalContentHandler.cs | 10 ++++++---- .../Views/AuditTrailEvent-Content.SummaryAdmin.cshtml | 4 ++-- ...nt - Copy.cshtml => AuditTrailEvent-Content.cshtml} | 0 5 files changed, 13 insertions(+), 9 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/{AuditTrailEvent-Content - Copy.cshtml => AuditTrailEvent-Content.cshtml} (100%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index cb1c4f668..3cec96393 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -136,7 +136,9 @@ - + + Code + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs index a301a1ae5..5cb577faa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -24,8 +24,8 @@ namespace Orchard.AuditTrail.Providers.Content { return; var eventData = (IDictionary)context.Shape.EventData; - var contentItemId = eventData.Get("ContentItemId"); - var previousContentItemVersionId = eventData.Get("PreviousContentItemVersionId"); + var contentItemId = eventData.Get("ContentId"); + var previousContentItemVersionId = eventData.Get("PreviousVersionId"); var contentItem = _contentManager.Value.Get(contentItemId); var previousVersion = previousContentItemVersionId > 0 ? _contentManager.Value.Get(contentItemId, VersionOptions.VersionRecord(previousContentItemVersionId)) : default(ContentItem); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index d49207b67..bac779ea0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -52,14 +52,16 @@ namespace Orchard.AuditTrail.Providers.Content { }; var eventData = new Dictionary { - {"ContentItemId", content.Id}, - {"ContentItemVersionId", content.ContentItem.VersionRecord.Id}, - {"ContentItemVersionNumber", content.ContentItem.VersionRecord.Number}, + {"ContentId", content.Id}, + {"ContentIdentity", _contentManager.GetItemMetadata(content).Identity.ToString()}, + {"VersionId", content.ContentItem.VersionRecord.Id}, + {"VersionNumber", content.ContentItem.VersionRecord.Number}, {"Title", title} }; if (previousContentItemVersion != null) { - eventData["PreviousContentItemVersionId"] = previousContentItemVersion.Id; + eventData["PreviousVersionId"] = previousContentItemVersion.Id; + eventData["PreviousVersionNumber"] = previousContentItemVersion.Number; } _auditTrailManager.CreateRecord( diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index cfd469ee6..e24c42468 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -2,8 +2,8 @@ @{ var eventData = (IDictionary) Model.EventData; var title = eventData.Get("Title"); - var contentItemId = eventData.Get("ContentItemId"); - var contentItemVersionNumber = eventData.Get("ContentItemVersionNumber"); + var contentItemId = eventData.Get("ContentId"); + var contentItemVersionNumber = eventData.Get("VersionNumber"); }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content - Copy.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content - Copy.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml From d1b84f15ca1682025f8d9cadeb9e8697f7a75576 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 1 Jul 2014 21:00:13 -0700 Subject: [PATCH 047/116] Fixed a model binding issue. --- .../Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index b5a211314..da3fa20c1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -46,7 +46,7 @@ namespace Orchard.AuditTrail.Drivers { }; if (updater != null) { - if (updater.TryUpdateModel(viewModel, Prefix, new[] { "IsEnabled" }, null)) { + if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { foreach (var eventSettingViewModel in viewModel.Categories.SelectMany(x => x.Events)) { var eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventSettingViewModel.Event); From f1276de0c2056efff22c2efca790b4ccaba1d927 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Tue, 1 Jul 2014 21:01:29 +0200 Subject: [PATCH 048/116] Added missing project references and dependencies to Orchard.AuditTrail. Added a publishing profile. --- .../Orchard.Azure.Web.csproj | 4 +++ src/Orchard.Azure/Orchard.Azure.sln | 28 +++++++++++++------ src/Orchard.Web/Orchard.Web.csproj | 1 + .../PublishProfiles/audittrail-test.pubxml | 24 ++++++++++++++++ src/Orchard.sln | 1 + 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj index 5a1c349de..672030822 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj +++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj @@ -245,6 +245,10 @@ Orchard.ArchiveLater True + + {3dd574cd-9c5d-4a45-85e1-ebba64c22b5f} + Orchard.AuditTrail + {66FCCD76-2761-47E3-8D11-B45D0001DDAA} Orchard.Autoroute diff --git a/src/Orchard.Azure/Orchard.Azure.sln b/src/Orchard.Azure/Orchard.Azure.sln index 6a0a74a5e..9dab33343 100644 --- a/src/Orchard.Azure/Orchard.Azure.sln +++ b/src/Orchard.Azure/Orchard.Azure.sln @@ -1,9 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +VisualStudioVersion = 12.0.30501.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}" + ProjectSection(SolutionItems) = preProject + ..\Orchard.Web\Modules\Orchard.AuditTrail\Orchard.AuditTrail.csproj = ..\Orchard.Web\Modules\Orchard.AuditTrail\Orchard.AuditTrail.csproj + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{75E7476C-C05B-4C41-8E38-081D3EB55659}" EndProject @@ -145,6 +148,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Templates", "..\Orc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Azure.MediaServices", "..\Orchard.Web\Modules\Orchard.Azure.MediaServices\Orchard.Azure.MediaServices.csproj", "{14A96B1A-9DC9-44C8-A675-206329E15263}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.AuditTrail", "..\Orchard.Web\Modules\Orchard.AuditTrail\Orchard.AuditTrail.csproj", "{3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -415,15 +420,22 @@ Global {14A96B1A-9DC9-44C8-A675-206329E15263}.Debug|Any CPU.Build.0 = Debug|Any CPU {14A96B1A-9DC9-44C8-A675-206329E15263}.Release|Any CPU.ActiveCfg = Release|Any CPU {14A96B1A-9DC9-44C8-A675-206329E15263}.Release|Any CPU.Build.0 = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} = {F2AB7512-139A-420F-AE3A-9ED22CA52CE1} + {9916839C-39FC-4CEB-A5AF-89CA7E87119F} = {F2AB7512-139A-420F-AE3A-9ED22CA52CE1} {63FBD4D9-E1DA-4A7B-AA6A-D6074FE50867} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {14C049FD-B35B-415A-A824-87F26B26E7FD} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {0E7646E8-FE8F-43C1-8799-D97860925EC4} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {EA2B9121-EF54-40A6-A53E-6593C86EE696} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} {17F86780-9A1F-4AA1-86F1-875EEC2730C7} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {72457126-E118-4171-A08F-9A709EE4B7FC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {D10AD48F-407D-4DB5-A328-173EC7CB010F} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} @@ -433,6 +445,7 @@ Global {CDE24A24-01D3-403C-84B9-37722E18DFB7} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {79AED36E-ABD0-4747-93D3-8722B042454B} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {954CA994-D204-468B-9D69-51F6AD3E1C29} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {33B1BC8D-E292-4972-A363-22056B207156} = {75E7476C-C05B-4C41-8E38-081D3EB55659} {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} @@ -441,16 +454,20 @@ Global {8F116B06-1C0E-4E4C-9A0A-D2FAB851E768} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {84650275-884D-4CBB-9CC0-67553996E211} {FBC8B571-ED50-49D8-8D9D-64AB7454A0D6} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {137906EA-15FE-4AD8-A6A0-27528F0477D6} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} {3420C92A-747F-4990-BA08-F2C9531E44AD} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {C889167C-E52C-4A65-A419-224B3D1B957D} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {99002B65-86F7-415E-BF4A-381AA8AB9CCC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {2AD6973D-C7BB-416E-89FE-EEE34664E05F} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {4A4595EF-6C37-4F99-96ED-4AE0B9E438D3} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {43D0EC0B-1955-4566-8D31-7B9102DA1703} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} {FC1D74E8-7A4D-48F4-83DE-95C6173780C4} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {3158C928-888C-4A84-8BC1-4A8257489538} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {6F759635-13D7-4E94-BCC9-80445D63F117} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} + {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} {3F72A4E9-7B72-4260-B010-C16EC54F9BAF} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {475B6C45-B27C-438B-8966-908B9D6D1077} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {66FCCD76-2761-47E3-8D11-B45D0001DDAA} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} @@ -475,13 +492,6 @@ Global {36B82383-D69E-4897-A24A-648BABDF80EC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {10AB3CE2-A720-467F-9EC8-EBB4BAC9A1C9} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} {14A96B1A-9DC9-44C8-A675-206329E15263} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} - {33B1BC8D-E292-4972-A363-22056B207156} = {75E7476C-C05B-4C41-8E38-081D3EB55659} - {CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {84650275-884D-4CBB-9CC0-67553996E211} - {9916839C-39FC-4CEB-A5AF-89CA7E87119F} = {F2AB7512-139A-420F-AE3A-9ED22CA52CE1} - {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} = {F2AB7512-139A-420F-AE3A-9ED22CA52CE1} - {137906EA-15FE-4AD8-A6A0-27528F0477D6} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} - {43D0EC0B-1955-4566-8D31-7B9102DA1703} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} - {966EC390-3C7F-4D98-92A6-F0F30D02E9B1} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} - {D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} = {B6092A92-1071-4C30-AD55-8E8D46BC2F14} + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D} EndGlobalSection EndGlobal diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index 66e4f2712..1cb4b6c81 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -158,6 +158,7 @@ + Web.config diff --git a/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml b/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml new file mode 100644 index 000000000..92b0744e9 --- /dev/null +++ b/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml @@ -0,0 +1,24 @@ + + + + + MSDeploy + Debug + Any CPU + http://audittrail-test.azurewebsites.net + True + True + audittrail-test.scm.azurewebsites.net:443 + audittrail-test + + True + WMSVC + True + $audittrail-test + <_SavePWD>True + <_DestinationType>AzureWebSite + + \ No newline at end of file diff --git a/src/Orchard.sln b/src/Orchard.sln index 68e001fdf..1a9be3e7f 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -69,6 +69,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Web", "Orchard.Web\ {2CF067CA-064B-43C6-8B88-5E3B99A65F1D} = {2CF067CA-064B-43C6-8B88-5E3B99A65F1D} {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} = {194D3CCC-1153-474D-8176-FDE8D7D0D0BD} {08191FCD-7258-4F19-95FB-AEC3DE77B2EB} = {08191FCD-7258-4F19-95FB-AEC3DE77B2EB} + {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F} = {3DD574CD-9C5D-4A45-85E1-EBBA64C22B5F} {ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {ABC826D4-2FA1-4F2F-87DE-E6095F653810} {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} = {D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} = {642A49D7-8752-4177-80D6-BFBBCFAD3DE0} From eb32aab0731df1b5eea1a366951d7457c3f02294 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 12:10:35 +0200 Subject: [PATCH 049/116] Renamed features and clarified their descriptions. --- .../Modules/Orchard.AuditTrail/Module.txt | 14 +++++++------- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 12 ++++++------ .../ContentDefinitionEventHandler.cs | 2 +- .../ContentPartAuditTrailEventProvider.cs | 2 +- .../ContentTypeAuditTrailEventProvider.cs | 2 +- .../GlobalContentDefinitionEditorEvents.cs | 2 +- .../Providers/{Role => Roles}/IRoleEventHandler.cs | 2 +- .../{Role => Roles}/RoleAuditTrailEventProvider.cs | 4 ++-- .../Providers/{Role => Roles}/RoleEventHandler.cs | 4 ++-- .../Providers/{User => Users}/IUserEventHandler.cs | 2 +- .../{User => Users}/UserAuditTrailEventProvider.cs | 4 ++-- .../Providers/{User => Users}/UserEventHandler.cs | 4 ++-- 12 files changed, 27 insertions(+), 27 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{Role => Roles}/IRoleEventHandler.cs (89%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{Role => Roles}/RoleAuditTrailEventProvider.cs (94%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{Role => Roles}/RoleEventHandler.cs (97%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{User => Users}/IUserEventHandler.cs (93%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{User => Users}/UserAuditTrailEventProvider.cs (91%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/{User => Users}/UserEventHandler.cs (95%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index ceccc1818..58de6621b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -21,18 +21,18 @@ Features: Description: Provides a background task that regularly deletes old audit trail records. Category: Security Dependencies: Orchard.AuditTrail - Orchard.AuditTrail.User: + Orchard.AuditTrail.Users: Name: Audit Trail User Events - Description: Provides event providers for user related events. + Description: Provides audit trail support for user related events. Category: Security Dependencies: Orchard.AuditTrail, Orchard.Users - Orchard.AuditTrail.Role: + Orchard.AuditTrail.Roles: Name: Audit Trail Role Events - Description: Provides event providers for role related events. + Description: Provides audit trail support for role related events. Category: Security Dependencies: Orchard.AuditTrail, Orchard.Roles - Orchard.AuditTrail.ContentTypeDefinition: - Name: Audit Trail Content Type Definition Events - Description: Provides event providers for content type definition related events. + Orchard.AuditTrail.ContentDefinition: + Name: Audit Trail Content Definition Events + Description: Provides audit trail support for content definition related events. Category: Security Dependencies: Orchard.AuditTrail, Orchard.ContentTypes \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 3cec96393..8d5aac77c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -204,12 +204,12 @@ - - - - - - + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs index 91f473263..cf9c96e86 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs @@ -5,7 +5,7 @@ using Orchard.ContentTypes.Events; using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { - [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] + [OrchardFeature("Orchard.AuditTrail.ContentDefinition")] public class ContentDefinitionEventHandler : IContentDefinitionEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs index dff523597..a803495fa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -3,7 +3,7 @@ using Orchard.AuditTrail.Services.Models; using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { - [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] + [OrchardFeature("Orchard.AuditTrail.ContentDefinition")] public class ContentPartAuditTrailEventProvider : AuditTrailEventProviderBase { public const string Created = "Created"; public const string Removed = "Removed"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index bf29d6f30..ca31abd1d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -7,7 +7,7 @@ using Orchard.ContentManagement.MetaData; using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { - [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] + [OrchardFeature("Orchard.AuditTrail.ContentDefinition")] public class ContentTypeAuditTrailEventProvider : AuditTrailEventProviderBase { private readonly IContentDefinitionManager _contentDefinitionManager; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index 6a4c36573..6b4216740 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -7,7 +7,7 @@ using Orchard.ContentManagement.ViewModels; using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { - [OrchardFeature("Orchard.AuditTrail.ContentTypeDefinition")] + [OrchardFeature("Orchard.AuditTrail.ContentDefinition")] public class GlobalContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs similarity index 89% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs index 40450a452..ddef5f9c0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/IRoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs @@ -1,6 +1,6 @@ using Orchard.Events; -namespace Orchard.AuditTrail.Providers.Role { +namespace Orchard.AuditTrail.Providers.Roles { public interface IRoleEventHandler : IEventHandler { void Created(dynamic context); void Removed(dynamic context); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs similarity index 94% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs index 2c0c301e6..58b080289 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs @@ -2,8 +2,8 @@ using Orchard.AuditTrail.Services.Models; using Orchard.Environment.Extensions; -namespace Orchard.AuditTrail.Providers.Role { - [OrchardFeature("Orchard.AuditTrail.Role")] +namespace Orchard.AuditTrail.Providers.Roles { + [OrchardFeature("Orchard.AuditTrail.Roles")] public class RoleAuditTrailEventProvider : AuditTrailEventProviderBase { public const string Created = "Created"; public const string Removed = "Removed"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs similarity index 97% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs index e73562a78..b63179143 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Role/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs @@ -3,8 +3,8 @@ using Orchard.AuditTrail.Services; using Orchard.Environment.Extensions; using Orchard.Security; -namespace Orchard.AuditTrail.Providers.Role { - [OrchardFeature("Orchard.AuditTrail.Role")] +namespace Orchard.AuditTrail.Providers.Roles { + [OrchardFeature("Orchard.AuditTrail.Roles")] public class RoleEventHandler : IRoleEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs similarity index 93% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs index be189b1c1..2b3342eb5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/IUserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs @@ -1,7 +1,7 @@ using Orchard.Events; using Orchard.Security; -namespace Orchard.AuditTrail.Providers.User { +namespace Orchard.AuditTrail.Providers.Users { public interface IUserEventHandler : IEventHandler { /// diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs similarity index 91% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs index 6bb5bb2d1..b4c122a9b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs @@ -2,8 +2,8 @@ using Orchard.AuditTrail.Services.Models; using Orchard.Environment.Extensions; -namespace Orchard.AuditTrail.Providers.User { - [OrchardFeature("Orchard.AuditTrail.User")] +namespace Orchard.AuditTrail.Providers.Users { + [OrchardFeature("Orchard.AuditTrail.Users")] public class UserAuditTrailEventProvider : AuditTrailEventProviderBase { public const string LoggedIn = "LoggedIn"; public const string LoggedOut = "LoggedOut"; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs similarity index 95% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs index fe58eb41a..449cd626c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/User/UserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs @@ -3,8 +3,8 @@ using Orchard.AuditTrail.Services; using Orchard.Environment.Extensions; using Orchard.Security; -namespace Orchard.AuditTrail.Providers.User { - [OrchardFeature("Orchard.AuditTrail.User")] +namespace Orchard.AuditTrail.Providers.Users { + [OrchardFeature("Orchard.AuditTrail.Users")] public class UserEventHandler : IUserEventHandler { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; From 660ab8322e672013b079c2e7f739b5adae3c554c Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 12:40:12 +0200 Subject: [PATCH 050/116] Changed the term "threshold" to "retention period" for clarity. --- .../AuditTrailTrimmingSettingsPartDriver.cs | 4 ++-- .../AuditTrailTrimmingSettingsPartHandler.cs | 12 +++++----- .../Models/AuditTrailTrimmingSettingsPart.cs | 10 ++++----- .../Services/AuditTrailManager.cs | 4 ++-- .../AuditTrailTrimmingBackgroundTask.cs | 2 +- .../Services/IAuditTrailManager.cs | 22 +++++++++---------- .../AuditTrailTrimmingSettingsViewModel.cs | 2 +- ...ailSettings-TrimmingSettingsChanged.cshtml | 6 ++--- .../Parts.AuditTrailTrimmingSettings.cshtml | 10 ++++----- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 0b3bb77a8..59c29a4a3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -24,12 +24,12 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { var viewModel = new AuditTrailTrimmingSettingsViewModel { - Threshold = part.Threshold, + RetentionPeriod = part.RetentionPeriod, }; if (updater != null) { if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { - part.Threshold = viewModel.Threshold; + part.RetentionPeriod = viewModel.RetentionPeriod; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs index 018943fdf..bd9636e3f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs @@ -10,7 +10,7 @@ using Orchard.Localization; namespace Orchard.AuditTrail.Handlers { [OrchardFeature("Orchard.AuditTrail.Trimming")] public class AuditTrailTrimmingSettingsPartHandler : ContentHandler { - private int _oldThreshold; + private int _oldRetentionPeriod; private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; @@ -31,21 +31,21 @@ namespace Orchard.AuditTrail.Handlers { } private void BeginUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { - _oldThreshold = part.Threshold; + _oldRetentionPeriod = part.RetentionPeriod; } private void EndUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { - var newThreshold = part.Threshold; + var newRetentionPeriod = part.RetentionPeriod; - if (newThreshold == _oldThreshold) + if (newRetentionPeriod == _oldRetentionPeriod) return; _auditTrailManager.CreateRecord( eventName: TrimmingSettingsAuditTrailEventProvider.TrimmingSettingsChanged, user: _wca.GetContext().CurrentUser, eventData: new Dictionary { - {"OldThreshold", _oldThreshold}, - {"NewThreshold", newThreshold} + {"OldRetentionPeriod", _oldRetentionPeriod}, + {"NewRetentionPeriod", newRetentionPeriod} }); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs index a9e36944d..8bec9677c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs @@ -4,15 +4,15 @@ using Orchard.ContentManagement; namespace Orchard.AuditTrail.Models { public class AuditTrailTrimmingSettingsPart : ContentPart { /// - /// Threshold in days. + /// Gets or sets the retention period in days of audit trail records before they are deleted. /// - public int Threshold { - get { return this.Retrieve(x => x.Threshold, defaultValue: 10); } - set { this.Store(x => x.Threshold, value); } + public int RetentionPeriod { + get { return this.Retrieve(x => x.RetentionPeriod, defaultValue: 10); } + set { this.Store(x => x.RetentionPeriod, value); } } /// - /// The timestamp the audit trail was last trimmed. + /// Gets or sets the time in UTC at which the audit trail was last trimmed. /// public DateTime? LastRunUtc { get { return this.Retrieve(x => x.LastRunUtc); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 844324fbd..f5f3f6ce8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -202,8 +202,8 @@ namespace Orchard.AuditTrail.Services { return eventDescriptors.First(); } - public IEnumerable Trim(TimeSpan threshold) { - var dateThreshold = _clock.UtcNow.Date - threshold; + public IEnumerable Trim(TimeSpan retentionPeriod) { + var dateThreshold = _clock.UtcNow.Date - retentionPeriod; var query = _auditTrailRepository.Table.Where(x => x.CreatedUtc < dateThreshold); var records = query.ToArray(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index 7c671318f..9bec00edd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -37,7 +37,7 @@ namespace Orchard.AuditTrail.Services { return; Logger.Debug("Starting audit trail trimming operation."); - var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.Threshold)); + var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.RetentionPeriod)); Logger.Debug("Audit trail trimming operation completed. {0} records were deleted.", deletedRecords.Count()); Settings.LastRunUtc = _clock.UtcNow; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index ba9d1e52a..031c0ea47 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -8,27 +8,27 @@ using Orchard.Security; namespace Orchard.AuditTrail.Services { public interface IAuditTrailManager : IDependency { /// - /// Gets a page of event records. + /// Returns a page of event records. /// /// The page number to get records from. /// The number of records to get. /// The value to order by. /// Optional. An object to filter the records on. - /// Returns a page of event records. + /// A page of event records. IPageOfItems GetRecords(int page, int pageSize, Filters filters = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending); /// /// Returns a single event record by ID. /// /// The event record ID. - /// Returns a single event record by ID. + /// A single event record by ID. AuditTrailEventRecord GetRecord(int id); /// /// Builds a shape tree of filter displays. /// /// Input for each filter builder. - /// Returns a tree of shapes. + /// A tree of shapes. dynamic BuildFilterDisplays(Filters filters); /// @@ -41,13 +41,13 @@ namespace Orchard.AuditTrail.Services { /// A property bag of custom event data that will be stored with the event record. /// The name of a custom key to use when filtering events. /// The value of a custom filter key to filter on. - /// Returns the created audit trail event record if the specified event was not disabled. + /// The created audit trail event record if the specified event was not disabled. AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider; /// /// Describes all audit trail events provided by the system. /// - /// Returns a list of audit trail category descriptors. + /// A list of audit trail category descriptors. IEnumerable DescribeCategories(); /// @@ -60,21 +60,21 @@ namespace Orchard.AuditTrail.Services { /// /// The scope of the specified event name. /// The shorthand name of the event. - /// Returns a single audit trail event descriptor. + /// A single audit trail event descriptor. AuditTrailEventDescriptor DescribeEvent(string eventName) where T : IAuditTrailEventProvider; /// /// Describes a single audit trail event. /// /// The fully qualified event name to describe. - /// Returns a single audit trail event descriptor. + /// A single audit trail event descriptor. AuditTrailEventDescriptor DescribeEvent(string fullyQualifiedEventName); /// - /// Trims the audit trail by deleting all records older than the specified threshold. + /// Trims the audit trail by deleting all records older than the specified retention period. /// - /// Returns the deleted records. - IEnumerable Trim(TimeSpan threshold); + /// A list of deleted records. + IEnumerable Trim(TimeSpan retentionPeriod); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs index d13d6920e..8b4a9868d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -1,5 +1,5 @@ namespace Orchard.AuditTrail.ViewModels { public class AuditTrailTrimmingSettingsViewModel { - public int Threshold { get; set; } + public int RetentionPeriod { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index 00249f063..6d77d88fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -1,10 +1,10 @@ @using Orchard.AuditTrail.Helpers @{ var eventData = (IDictionary)Model.EventData; - var oldThreshold = eventData.Get("OldThreshold"); - var newThreshold = eventData.Get("NewThreshold"); + var oldRetentionPeriod = eventData.Get("OldRetentionPeriod"); + var newRetentionPeriod = eventData.Get("NewRetentionPeriod"); }
- @T("Trimming threshold changed from {0} to {1}", oldThreshold, newThreshold) + @T("Trimming retention period changed from {0} to {1}", oldRetentionPeriod, newRetentionPeriod)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index afb4a8df5..60c98ed7a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -1,9 +1,9 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailTrimmingSettingsViewModel
- @T("Auto Trim Settings") -
- @Html.LabelFor(m => m.Threshold, T("Auto-trim threshold")) - @Html.TextBoxFor(m => m.Threshold, new { @class = "text small" }) - @T("Specify the number of days of audit log data to retain.") + @T("Trimming Settings") +
+ @Html.LabelFor(m => m.RetentionPeriod, T("Retention period")) + @Html.TextBoxFor(m => m.RetentionPeriod, new { @class = "text small" }) + @T("The number of days of audit log data to retain.")
\ No newline at end of file From 66aa1426dcbeead0d22aba8e8571a290913d570d Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 13:54:13 +0200 Subject: [PATCH 051/116] Refactored the audit trail settings UI and cleaned up a bunch of UI strings. Renamed some resource files. --- .../Orchard.AuditTrail.csproj | 6 +- .../SettingsAuditTrailEventProvider.cs | 2 +- ...TrimmingSettingsAuditTrailEventProvider.cs | 2 +- .../Content/ContentAuditTrailEventProvider.cs | 12 +-- .../ContentPartAuditTrailEventProvider.cs | 16 ++-- .../Roles/RoleAuditTrailEventProvider.cs | 6 +- .../Users/UserAuditTrailEventProvider.cs | 6 +- .../Scripts/audit-trail-admin.js | 49 ---------- .../Scripts/audittrail-admin.js | 24 +++++ .../Scripts/audittrail-checkall.js | 23 +++++ .../Orchard.AuditTrail/Styles/admin.css | 52 ---------- .../Styles/audittrail-admin.css | 40 ++++++++ .../Styles/audittrail-settings.css | 15 +++ .../Views/Admin/Detail.cshtml | 2 +- .../Views/Admin/Index.cshtml | 2 +- .../Views/Content/Detail.cshtml | 4 +- .../Parts.AuditTrailSettings.cshtml | 96 ++++++++++--------- .../Parts.AuditTrailTrimmingSettings.cshtml | 14 ++- .../Views/Parts.AuditTrail.cshtml | 2 +- 19 files changed, 188 insertions(+), 185 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-checkall.js delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings.css diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 8d5aac77c..6ac335f22 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -78,8 +78,10 @@ - - + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs index deeab756c..94ff07b21 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs @@ -8,7 +8,7 @@ namespace Orchard.AuditTrail.Providers.AuditTrail { public override void Describe(DescribeContext context) { context.For("AuditTrailSettings", T("Audit Trail Settings")) - .Event(this, EventsChanged, T("Events Changed"), T("Audit Trail event settings were changed."), enableByDefault: true, isMandatory: true); + .Event(this, EventsChanged, T("Events changed"), T("Audit trail event settings were changed."), enableByDefault: true, isMandatory: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs index 6f2ce0884..ffdc2760d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs @@ -10,7 +10,7 @@ namespace Orchard.AuditTrail.Providers.AuditTrail { public override void Describe(DescribeContext context) { context.For("AuditTrailSettings", T("Audit Trail Settings")) - .Event(this, TrimmingSettingsChanged, T("Trimming Settings Changed"), T("Audit Trail trimming settings were changed."), enableByDefault: true); + .Event(this, TrimmingSettingsChanged, T("Trimming settings changed"), T("Audit trail trimming settings were changed."), enableByDefault: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs index 4b3f2819b..1624e54de 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs @@ -25,12 +25,12 @@ namespace Orchard.AuditTrail.Providers.Content { } public override void Describe(DescribeContext context) { - context.For("Content", T("Content")) - .Event(this, Created, T("Created"), T("Content was created."), enableByDefault: true) - .Event(this, Saved, T("Saved"), T("Content was saved."), enableByDefault: true) - .Event(this, Published, T("Published"), T("Content was published."), enableByDefault: true) - .Event(this, Unpublished, T("Unpublished"), T("Content was unpublished."), enableByDefault: true) - .Event(this, Removed, T("Removed"), T("Content was deleted."), enableByDefault: true); + context.For("Content", T("Content Items")) + .Event(this, Created, T("Created"), T("A content item was created."), enableByDefault: true) + .Event(this, Saved, T("Saved"), T("A content item was saved."), enableByDefault: true) + .Event(this, Published, T("Published"), T("A content item was published."), enableByDefault: true) + .Event(this, Unpublished, T("Unpublished"), T("A content item was unpublished."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("A content item was deleted."), enableByDefault: true); context.QueryFilter(QueryFilter); context.DisplayFilter(DisplayFilter); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs index a803495fa..5d8e6348e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -14,14 +14,14 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public const string FieldSettingsUpdated = "FieldSettingsUpdated"; public override void Describe(DescribeContext context) { - context.For("ContentPart", T("Content Part")) - .Event(this, Created, T("Created"), T("Content Type was created."), enableByDefault: true) - .Event(this, Removed, T("Removed"), T("Content Type was removed."), enableByDefault: true) - .Event(this, DescriptionChanged, T("Description changed"), T("Content Part description was changed."), enableByDefault: true) - .Event(this, FieldAdded, T("Field added"), T("Content Field was added."), enableByDefault: true) - .Event(this, FieldRemoved, T("Field removed"), T("Content Field was removed."), enableByDefault: true) - .Event(this, PartSettingsUpdated, T("Part settings updated"), T("Content Part settings were updated."), enableByDefault: true) - .Event(this, FieldSettingsUpdated, T("Field settings updated"), T("Content Field settings were updated."), enableByDefault: true); + context.For("ContentPart", T("Content Parts")) + .Event(this, Created, T("Created"), T("A content type was created."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("A content type was removed."), enableByDefault: true) + .Event(this, DescriptionChanged, T("Description changed"), T("A content part description was changed."), enableByDefault: true) + .Event(this, FieldAdded, T("Field added"), T("A field was added to a content part."), enableByDefault: true) + .Event(this, FieldRemoved, T("Field removed"), T("A field was removed from a content part."), enableByDefault: true) + .Event(this, PartSettingsUpdated, T("Part settings updated"), T("The settings of a content part were updated."), enableByDefault: true) + .Event(this, FieldSettingsUpdated, T("Field settings updated"), T("The settings of a field on a content part were updated."), enableByDefault: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs index 58b080289..fbc21667b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleAuditTrailEventProvider.cs @@ -14,12 +14,12 @@ namespace Orchard.AuditTrail.Providers.Roles { public const string UserRemoved = "UserRemoved"; public override void Describe(DescribeContext context) { - context.For("Role", T("Role")) + context.For("Role", T("Roles")) .Event(this, Created, T("Created"), T("A role was created."), enableByDefault: true) .Event(this, Removed, T("Removed"), T("A role was removed."), enableByDefault: true) .Event(this, Renamed, T("Renamed"), T("A role was renamed."), enableByDefault: true) - .Event(this, PermissionAdded, T("Permission added"), T("Permission was added to a role."), enableByDefault: true) - .Event(this, PermissionRemoved, T("Permission removed"), T("Permission was removed from a role."), enableByDefault: true) + .Event(this, PermissionAdded, T("Permission added"), T("A permission was added to a role."), enableByDefault: true) + .Event(this, PermissionRemoved, T("Permission removed"), T("A permission was removed from a role."), enableByDefault: true) .Event(this, UserAdded, T("User added"), T("A user was added to a role."), enableByDefault: true) .Event(this, UserRemoved, T("User removed"), T("A user was removed from a role."), enableByDefault: true); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs index b4c122a9b..1ce794ca1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserAuditTrailEventProvider.cs @@ -11,10 +11,10 @@ namespace Orchard.AuditTrail.Providers.Users { public const string PasswordChanged = "PasswordChanged"; public override void Describe(DescribeContext context) { - context.For("User", T("User")) + context.For("User", T("Users")) .Event(this, LoggedIn, T("Logged in"), T("A user was successfully logged in."), enableByDefault: true) - .Event(this, LoggedOut, T("Logged out"), T("A user explicitly logged out."), enableByDefault: true) - .Event(this, LogInFailed, T("Login failed"), T("An attempt to login failed due to an incorrect username/email and/or password."), enableByDefault: true) + .Event(this, LoggedOut, T("Logged out"), T("A user actively logged out."), enableByDefault: true) + .Event(this, LogInFailed, T("Login failed"), T("An attempt to login failed due to incorrect credentials."), enableByDefault: true) .Event(this, PasswordChanged, T("Password changed"), T("A user's password was changed."), enableByDefault: true); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js deleted file mode 100644 index 519fa06df..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audit-trail-admin.js +++ /dev/null @@ -1,49 +0,0 @@ -(function($) { - - var initExpandoControl = function() { - $(".expando-wrapper legend").expandoControl( - function(controller) { - return controller.nextAll(".expando"); - }, { - collapse: true, - remember: true - }); - }; - - var initCheckAll = function() { - $("table.check-all").each(function() { - var table = $(this); - var controller = table.find("thead input[type=\"checkbox\"]"); - var checkboxes = table.find("tbody input[type=\"checkbox\"]:not(:disabled)"); - - var updateController = function () { - var allChecked = checkboxes.filter(":not(:checked)").length == 0; - controller.prop("checked", allChecked); - } - - table.on("change", "thead input[type=\"checkbox\"]", function() { - var isChecked = $(this).is(":checked"); - checkboxes.prop("checked", isChecked); - }); - - table.on("change", "tbody input[type=\"checkbox\"]", function () { - updateController(); - }); - - updateController(); - }); - }; - - var disableContentEditor = function () { - $(".content-disabled input").prop("disabled", true); - $(".content-disabled textarea").prop("disabled", true); - $(".content-disabled button").prop("disabled", true); - }; - - $(function() { - initExpandoControl(); - initCheckAll(); - disableContentEditor(); - }); - -})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js new file mode 100644 index 000000000..a24963747 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js @@ -0,0 +1,24 @@ +(function($) { + + var initExpandoControl = function() { + $(".expando-wrapper legend").expandoControl( + function(controller) { + return controller.nextAll(".expando"); + }, { + collapse: true, + remember: true + }); + }; + + var disableContentEditor = function () { + $(".content-disabled input").prop("disabled", true); + $(".content-disabled textarea").prop("disabled", true); + $(".content-disabled button").prop("disabled", true); + }; + + $(function() { + initExpandoControl(); + disableContentEditor(); + }); + +})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-checkall.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-checkall.js new file mode 100644 index 000000000..a11fea70f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-checkall.js @@ -0,0 +1,23 @@ +$(function () { + $(".check-all-container").each(function () { + var container = $(this); + var master = container.find("input[type=\"checkbox\"].check-all-master"); + var slaves = container.find("input[type=\"checkbox\"]:not(:disabled).check-all-slave"); + + var updateMaster = function () { + var allChecked = slaves.filter(":not(:checked)").length == 0; + master.prop("checked", allChecked); + } + + master.on("change", function () { + var isChecked = $(this).is(":checked"); + slaves.prop("checked", isChecked); + }); + + slaves.on("change", function () { + updateMaster(); + }); + + updateMaster(); + }); +}); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css deleted file mode 100644 index 0a9638f24..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/admin.css +++ /dev/null @@ -1,52 +0,0 @@ -.audit-trail-filter { - margin-bottom: 1em; -} - - .audit-trail-filter fieldset label { - display: inline-block; - width: 10em; - } - - .audit-trail-filter fieldset label.inline { - display: inline; - width: auto; - } - -.audit-trail-list .info { - line-height: 25px; -} - -.audit-trail-list .event-content .version { - font-size: 0.8em; -} - -.audit-trail-event fieldset legend span { - font-size: 0.8em; -} - -.audit-trail-site-settings table th.event-name { - width: 250px; -} - -.audit-trail-site-settings table th.event-enabled { - width: 60px; -} - -.content-disabled { - position: relative; -} - -.content-disabled .overlay { - position: absolute; - left: -24px; - top: -16px; - right: -24px; - bottom: -28px; - background: url('overlay.png'); -} - -.content-disabled .edit-item-secondary, -.content-disabled .audit-trail.expando-wrapper, -.content-disabled .audit-trail-link { - display: none; -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css new file mode 100644 index 000000000..432c5e283 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css @@ -0,0 +1,40 @@ +.audit-trail-filter { + margin-bottom: 1em; +} + + .audit-trail-filter fieldset label { + display: inline-block; + width: 10em; + } + + .audit-trail-filter fieldset label.inline { + display: inline; + width: auto; + } + +.audit-trail-list .info { + line-height: 25px; +} + +.audit-trail-list .event-content .version { + font-size: 0.8em; +} + +.content-disabled { + position: relative; +} + + .content-disabled .overlay { + position: absolute; + left: -24px; + top: -16px; + right: -24px; + bottom: -28px; + background: url('overlay.png'); + } + + .content-disabled .edit-item-secondary, + .content-disabled .audit-trail.expando-wrapper, + .content-disabled .audit-trail-link { + display: none; + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings.css new file mode 100644 index 000000000..cf764eae3 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings.css @@ -0,0 +1,15 @@ +.audittrail-settings-section table.audittrail-events-table { + width: auto; + min-width: 600px; + margin-top: 1em; +} + +.audittrail-settings-section tbody.audittrail-category-body tr th { + background-color: #ebebeb; + font-size: 1.1em; + font-weight: bold; +} + +.audittrail-settings-section .audittrail-events-table .audittrail-event-enabled-cell { + text-align: right; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml index 3b06415e9..e94b9d225 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml @@ -1,6 +1,6 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailDetailsViewModel @{ - Style.Include("admin.css"); + Style.Include("audittrail-admin.css"); } @{ var record = Model.Record; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index 6fb0cacb4..ba0867ef2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -2,7 +2,7 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ Style.Include("custom-grid.css"); - Style.Include("admin.css"); + Style.Include("audittrail-admin.css"); var orderBy = Model.OrderBy; var orderByItems = new List { new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml index 4987192f0..c60ff6204 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml @@ -1,9 +1,9 @@ @using Orchard.ContentManagement @{ - Style.Include("admin.css"); + Style.Include("audittrail-admin.css"); Script.Require("ShapesBase"); Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); - Script.Include("audit-trail-admin.js").AtFoot(); + Script.Include("audittrail-admin.js").AtFoot(); var contentItem = (ContentItem)Model.ContentItem; Layout.Title = T("{0} - (version {1})", contentItem.ContentType, contentItem.Version); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index f1051e37b..144acecf5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -1,51 +1,53 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailSettingsViewModel @{ - Style.Include("admin.css"); + Style.Include("audittrail-settings.css"); Script.Require("ShapesBase"); - Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); - Script.Include("audit-trail-admin.js").AtFoot(); + //Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); + Script.Include("audittrail-checkall.js").AtFoot(); } -
-
- @T("Specify the events to audit") - @{ - var i = 0; - } - @foreach (var category in Model.Categories) { -
- @category.Name - -
@evnt.Description - checked="checked"} /> + checked="checked"} @if(evnt.IsMandatory){disabled="disabled"}/>
- - - - - - - - @{ var j = 0; } - @foreach (var evnt in category.Events) { - var checkboxId = String.Format("Event{0}{1}", i, j); - - - - - - j++; - } -
@T("Event")@T("Description") - -
- - @evnt.Name - @evnt.Description - checked="checked"} @if(evnt.IsMandatory){disabled="disabled"}/> -
-
- i++; - } -
- \ No newline at end of file +
+

@T("Events to record in the audit trail")

+ + + + + + + + + @{ var i = 0; } + @foreach (var category in Model.Categories) { + + + + + + @{ var j = 0; } + @foreach (var e in category.Events) { + var checkboxId = String.Format("Event{0}{1}", i, j); + + + + + + j++; + } + + i++; + } +
@T("Event")@T("Description") + +
+ @category.Name + + + +
+ + @e.Name + @e.Description + checked="checked" } @if (e.IsMandatory) { disabled="disabled" } /> +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index 60c98ed7a..61b11ae6b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -1,9 +1,7 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailTrimmingSettingsViewModel -
- @T("Trimming Settings") -
- @Html.LabelFor(m => m.RetentionPeriod, T("Retention period")) - @Html.TextBoxFor(m => m.RetentionPeriod, new { @class = "text small" }) - @T("The number of days of audit log data to retain.") -
-
\ No newline at end of file +
+

@T("Trimming settings")

+ @Html.LabelFor(m => m.RetentionPeriod, T("Retention period")) + @Html.TextBoxFor(m => m.RetentionPeriod, new { @class = "text small" }) + @T("The number of days of audit log data to retain.") +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index dee36c96b..218ae43e9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -3,7 +3,7 @@ @{ Script.Require("ShapesBase"); Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); - Script.Include("audit-trail-admin.js").AtFoot(); + Script.Include("audittrail-admin.js").AtFoot(); } @{ var records = (IEnumerable)Model.Records; From f96e73fc4c0729036eb00b45fd34596bddced4a5 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 17:19:21 +0200 Subject: [PATCH 052/116] Refactored resources. Inlined small PNG images. --- .../Modules/Orchard.AuditTrail/AdminMenu.cs | 2 +- .../Orchard.AuditTrail.csproj | 6 +++--- .../Scripts/audittrail-admin.js | 7 ------ .../Scripts/audittrail-disabledcontent.js | 5 +++++ .../Styles/audittrail-admin.css | 20 ------------------ .../Styles/audittrail-disabledcontent.css | 19 +++++++++++++++++ .../{custom-grid.css => audittrail-grid.css} | 0 .../Styles/menu.audit-trail-admin.css | 8 +++---- .../Styles/menu.audit-trail.png | Bin 1104 -> 0 bytes .../Orchard.AuditTrail/Styles/overlay.png | Bin 1146 -> 0 bytes .../Views/Admin/Index.cshtml | 2 +- .../Views/AuditTrailFilter-ContentType.cshtml | 2 +- .../Views/Content/Detail.cshtml | 10 ++++----- 13 files changed, 39 insertions(+), 42 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-disabledcontent.js create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-disabledcontent.css rename src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/{custom-grid.css => audittrail-grid.css} (100%) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs index 81f4192bc..83de97663 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/AdminMenu.cs @@ -6,7 +6,7 @@ namespace Orchard.AuditTrail { public string MenuName { get { return "admin"; } } public void GetNavigation(NavigationBuilder builder) { - builder.AddImageSet("audit-trail") + builder.AddImageSet("audittrail") .Add(T("Audit Trail"), "12", menuItem => menuItem .Action("Index", "Admin", new { area = "Orchard.AuditTrail" }) .Permission(Permissions.ManageAuditTrailSettings)); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 6ac335f22..8de6c80fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -80,12 +80,12 @@ + + - + - - diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js index a24963747..5399f17e9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js @@ -10,15 +10,8 @@ }); }; - var disableContentEditor = function () { - $(".content-disabled input").prop("disabled", true); - $(".content-disabled textarea").prop("disabled", true); - $(".content-disabled button").prop("disabled", true); - }; - $(function() { initExpandoControl(); - disableContentEditor(); }); })(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-disabledcontent.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-disabledcontent.js new file mode 100644 index 000000000..e8957b17e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-disabledcontent.js @@ -0,0 +1,5 @@ +$(function () { + $(".disabled-content-wrapper input").prop("disabled", true); + $(".disabled-content-wrapper textarea").prop("disabled", true); + $(".disabled-content-wrapper button").prop("disabled", true); +}); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css index 432c5e283..049504af7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css @@ -9,7 +9,6 @@ .audit-trail-filter fieldset label.inline { display: inline; - width: auto; } .audit-trail-list .info { @@ -19,22 +18,3 @@ .audit-trail-list .event-content .version { font-size: 0.8em; } - -.content-disabled { - position: relative; -} - - .content-disabled .overlay { - position: absolute; - left: -24px; - top: -16px; - right: -24px; - bottom: -28px; - background: url('overlay.png'); - } - - .content-disabled .edit-item-secondary, - .content-disabled .audit-trail.expando-wrapper, - .content-disabled .audit-trail-link { - display: none; - } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-disabledcontent.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-disabledcontent.css new file mode 100644 index 000000000..9e7207c04 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-disabledcontent.css @@ -0,0 +1,19 @@ + +.disabled-content-wrapper { + position: relative; +} + +.disabled-content-overlay { + position: absolute; + left: -24px; + top: -16px; + right: -24px; + bottom: -28px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEE1QTFEQkIwMTgzMTFFNDg4ODhCRjg2N0VEQjAxNTUiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEE1QTFEQkEwMTgzMTFFNDg4ODhCRjg2N0VEQjAxNTUiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjg0Q0EwN0U3RjRCMTExRTM4MDlCRkYyQzE5M0JCODI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjg0Q0EwN0U4RjRCMTExRTM4MDlCRkYyQzE5M0JCODI3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Xw2MNgAAAO9JREFUeNrs0gENAAAIwzDAv+djg4RWwrJOUvw1EhgAA2AADIABMAAGwAAYAANgAAyAATAABsAAGAADYAAMgAEwAAbAABgAA2AADIABMAAGwAAYAANgAAyAATAABsAAGAADYAAMgAEwAAbAABgAA2AADIABMAAGwAAYAANgAAyAATAABsAAGAADYAAMgAEwAAbAABgAA2AADIABMAAGwAAYAANgAAyAAQwggQEwAAbAABgAA2AADIABMAAGwAAYAANgAAyAATAABsAAGAADYAAMgAEwAAbAABgAA2AADIABMAAGwAAYAANgAAzADSvAAO13A/2zPw4VAAAAAElFTkSuQmCC'); +} + +.disabled-content-wrapper .edit-item-secondary, +.disabled-content-wrapper .audit-trail.expando-wrapper, +.disabled-content-wrapper .audit-trail-link { + display: none; +} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css similarity index 100% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/custom-grid.css rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css index 33d56b7cb..ce4933cdf 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail-admin.css @@ -1,7 +1,7 @@ .navicon-audit-trail { - background-image:url(menu.audit-trail.png) !important; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAwCAYAAAAYX/pXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0QjYzNzBCRkUyQUExMUUzQjhEQkUxOEU0QTJCQjdGQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0QjYzNzBDMEUyQUExMUUzQjhEQkUxOEU0QTJCQjdGQyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRCNjM3MEJERTJBQTExRTNCOERCRTE4RTRBMkJCN0ZDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRCNjM3MEJFRTJBQTExRTNCOERCRTE4RTRBMkJCN0ZDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+a9wktAAAAMVJREFUeNrsllEOwiAMhvcTLqTPegg9qB5Cn/VIdRq3dM0PrcEHXWhCwtbt7wcUCkRkaLGsHwDM/dPlZpVx3G9fHR001dQPuw2eLUxAomqT0T/TUAHjlPP1Luy9/rg0BCHo4g5BRxujL1BLViOYour2TwR2uUJ5YGYcJCq+TpBI+uo1X8zB2+cTTEnk7QMqYNLXNbSeB2lotC7QBbrAagRyrRp7J3KEAN7JnCMVmPhi94PCT7H7AUFfa23sBL9K8FG9fwgwAMe/S7wfx1otAAAAAElFTkSuQmCC') !important; } -.navicon-audit-trail:hover { - background-position:0 -30px !important; -} \ No newline at end of file + .navicon-audit-trail:hover { + background-position: 0 -30px !important; + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/menu.audit-trail.png deleted file mode 100644 index a35718a2a6ecd43a030767a5df59dd097c0a9dd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1104 zcmaJ=TWHfz7>+pI7*2&L=)A>LP>0Q>Yn=_NvuRpaU1zPu6+yNvIbE}woS2;2c0LFy zf^UKs_8=3~2Opdu47|?iKtxcy%nRu7!3&B^6vPXP;z?br57xlRx$u48|NZ~@&;DrJ z+M4RRYJwnY!YyJ9&ol90tES@roQ`kpc$$lX3A70&QC2bm;a6Z6Aj6u}4Pro2^4o8M zCW4r}SdAx8BGSssP@^RqL+3ODvk9W9IcG?68X&R@bgR0LdVgt{B2~plwR<9L#0Y?t z+R|%+O}%Y#xi>9)6{>kP*_7k4fCi96=Cp0P#pirfL6^sC`cwC&g1rS+zQggat#c}GA^%^<9K%?&#fdUJ_<)Ol_Vb%Lld#^&PSyX zGI)l`X0vp*fre%`!+E`4hIKJ6mlGqLR$fO^&Z%3DqJju4*;EarLY=e~r7oC3J_99i? ze82<}f@U1TZN(}^QxHKb1r0I~AeXhPx&pJ-@&Y^(;lsLxBwYq!(MMqcT2&R^Ev#&4 zWQ9=B<@a-3ut8WQ3PEmF(Cv2#LSraUcTje{oP&oFfB~y0}-JUUUt#WHh7@b)p-v0#Dw;e#2MYWkh6YmWCEyw^M$o%G_+$4~V5(9iSkip6i9Pxr5# zcY=wo-|Xl+{`T{RiX9h(d}nh0lKLxc2U@p02_VjgaYxw26$@QK0AA1J-E7jB> zeRs;mt34IwK;6!z=3e62&7+RleP6r2>>1f`_WLA%M_L=N7+&{b(5 QTb%YA4+q=CGeYO?UqyFvR{#J2 diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/overlay.png deleted file mode 100644 index 9524f28bc549a0a8a1a743894885e24e67aa97a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1146 zcmc&zKX21O6u+ucRaFfG5)v>S?gE1Nd`_I$R^2ML6B>y`RT|N3)Uhv()!Jw5D|S1T zKMN9{g#ku}Msz}KjC=tWP`?03oYSOb2wfO>l707{-tWEN`*W{1+Ybv%x0e6_h31Cc z;pcJwEiUl?>6-JIAGcV&$F}HzrA|yh&7*w+n}M@SI>hk~pMD~%0LlUTAR?KF@cJx6kSQiu&RkzDQg%% zfU<;32un!TiWuwVs*WpgA_C7Adjq{=Hzv8bW(Y&ZA|0VLO~te%(s&nPP1BGhBUvtT zk79BdGAApB$;vc>O%gZuBj(c(<`JDfJz$2wnVy#rM6K3E;4qmqink19PK2;1p&-cX z8hajtyJqaw<*dL+YA%tgf5w4{Yz}^N~~_h#9=hCe*M}F Oz@=Gl+i%UC7rz1ckV2IJ diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index ba0867ef2..f61981d93 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -1,8 +1,8 @@ @using Orchard.AuditTrail.Services.Models @model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ - Style.Include("custom-grid.css"); Style.Include("audittrail-admin.css"); + Style.Include("audittrail-grid.css"); var orderBy = Model.OrderBy; var orderByItems = new List { new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml index 74fe52719..06a019262 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml @@ -5,6 +5,6 @@ var listItems = contentTypes.Select(x => new SelectListItem {Text = x.DisplayName, Value = x.Name, Selected = x.Name == currentContentType}); }
- @Html.Label("contenttype", T("Content Type:").Text) + @Html.Label("contenttype", T("Content type:").Text) @Html.DropDownList("contenttype", listItems, "")
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml index c60ff6204..86f4cbfa1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Content/Detail.cshtml @@ -1,14 +1,14 @@ @using Orchard.ContentManagement @{ - Style.Include("audittrail-admin.css"); + Style.Include("audittrail-disabledcontent.css"); Script.Require("ShapesBase"); Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); - Script.Include("audittrail-admin.js").AtFoot(); + Script.Include("audittrail-disabledcontent.js").AtFoot(); var contentItem = (ContentItem)Model.ContentItem; - Layout.Title = T("{0} - (version {1})", contentItem.ContentType, contentItem.Version); + Layout.Title = T("{0} - {1} (version {2})", contentItem.ContentType, Html.ItemDisplayText(contentItem), contentItem.Version); } -
+
@Display(Model) -
+
\ No newline at end of file From f66affe98cf199f26812a8f76a39b460a45c4732 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 19:08:40 +0200 Subject: [PATCH 053/116] Miscellaneous tweaks, refactorings and renames. --- .../Controllers/AdminController.cs | 1 - .../Orchard.AuditTrail.csproj | 5 +- .../ContentTypeAuditTrailEventProvider.cs | 12 +-- .../Scripts/audittrail-admin.js | 17 ---- .../Scripts/audittrail-expando.js | 11 +++ .../Styles/audittrail-admin.css | 20 ----- .../Styles/audittrail-display.css | 20 +++++ .../Styles/audittrail-part.css | 7 ++ .../Views/Admin/Detail.cshtml | 24 +++--- .../Views/Admin/Index.cshtml | 16 ++-- ...ailSettings-TrimmingSettingsChanged.cshtml | 4 +- ...uditTrailEvent-Content.SummaryAdmin.cshtml | 7 +- .../Views/AuditTrailEvent-Content.cshtml | 71 ++++++++------- ...nt-ContentPart-Created.SummaryAdmin.cshtml | 2 +- ...AuditTrailEvent-ContentPart-Created.cshtml | 2 +- ...ContentPart-FieldAdded.SummaryAdmin.cshtml | 2 +- ...itTrailEvent-ContentPart-FieldAdded.cshtml | 2 +- ...ntentPart-FieldRemoved.SummaryAdmin.cshtml | 2 +- ...TrailEvent-ContentPart-FieldRemoved.cshtml | 2 +- ...t-FieldSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...nt-ContentPart-FieldSettingsUpdated.cshtml | 2 +- ...rt-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ent-ContentPart-PartSettingsUpdated.cshtml | 2 +- ...nt-ContentPart-Removed.SummaryAdmin.cshtml | 2 +- ...AuditTrailEvent-ContentPart-Removed.cshtml | 2 +- ...nt-ContentType-Created.SummaryAdmin.cshtml | 2 +- ...AuditTrailEvent-ContentType-Created.cshtml | 2 +- ...-ContentType-PartAdded.SummaryAdmin.cshtml | 2 +- ...ditTrailEvent-ContentType-PartAdded.cshtml | 2 +- ...ontentType-PartRemoved.SummaryAdmin.cshtml | 2 +- ...tTrailEvent-ContentType-PartRemoved.cshtml | 2 +- ...pe-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ent-ContentType-PartSettingsUpdated.cshtml | 2 +- ...nt-ContentType-Removed.SummaryAdmin.cshtml | 2 +- ...AuditTrailEvent-ContentType-Removed.cshtml | 2 +- ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ent-ContentType-TypeSettingsUpdated.cshtml | 2 +- ...t-Role-PermissionAdded.SummaryAdmin.cshtml | 2 +- ...uditTrailEvent-Role-PermissionAdded.cshtml | 2 +- ...Role-PermissionRemoved.SummaryAdmin.cshtml | 2 +- ...itTrailEvent-Role-PermissionRemoved.cshtml | 2 +- ...Event-Role-RoleCreated.SummaryAdmin.cshtml | 2 +- .../AuditTrailEvent-Role-RoleCreated.cshtml | 2 +- ...Event-Role-RoleRenamed.SummaryAdmin.cshtml | 2 +- .../AuditTrailEvent-Role-RoleRenamed.cshtml | 2 +- .../AuditTrailEvent-User-LoginFailed..cshtml | 2 +- .../AuditTrailEvent-User.SummaryAdmin.cshtml | 2 +- .../Views/AuditTrailEvent-User.cshtml | 2 +- .../Views/Parts.AuditTrail.cshtml | 86 +++++++++---------- 49 files changed, 186 insertions(+), 185 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-expando.js delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-part.css diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 5c8e4176a..62562006f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -27,7 +27,6 @@ namespace Orchard.AuditTrail.Controllers { public dynamic New { get; private set; } public ActionResult Index(PagerParameters pagerParameters, AuditTrailOrderBy? orderBy = null) { - if(!_authorizer.Authorize(Permissions.ViewAuditTrail)) return new HttpUnauthorizedResult(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 8de6c80fe..845d40c91 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -78,11 +78,12 @@ - + - + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index ca31abd1d..67196735d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -24,12 +24,12 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public override void Describe(DescribeContext context) { context.For("ContentType", T("Content Type")) - .Event(this, Created, T("Created"), T("Content Type was created."), enableByDefault: true) - .Event(this, Removed, T("Removed"), T("Content Type was removed."), enableByDefault: true) - .Event(this, PartAdded, T("Part added"), T("Content Part was added."), enableByDefault: true) - .Event(this, PartRemoved, T("Part removed"), T("Content Part was removed."), enableByDefault: true) - .Event(this, TypeSettingsUpdated, T("Type Settings updated"), T("Content Type settings were updated."), enableByDefault: true) - .Event(this, PartSettingsUpdated, T("Part Settings updated"), T("Content Part settings were updated."), enableByDefault: true); + .Event(this, Created, T("Created"), T("A content type was created."), enableByDefault: true) + .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, 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 were updated."), enableByDefault: true); context.QueryFilter(QueryFilter); context.DisplayFilter(DisplayFilter); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js deleted file mode 100644 index 5399f17e9..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-admin.js +++ /dev/null @@ -1,17 +0,0 @@ -(function($) { - - var initExpandoControl = function() { - $(".expando-wrapper legend").expandoControl( - function(controller) { - return controller.nextAll(".expando"); - }, { - collapse: true, - remember: true - }); - }; - - $(function() { - initExpandoControl(); - }); - -})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-expando.js b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-expando.js new file mode 100644 index 000000000..33bc48f81 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Scripts/audittrail-expando.js @@ -0,0 +1,11 @@ +$(function() { + $(".expando-wrapper > legend").expandoControl( + function(controller) { + return controller.nextAll(".expando"); + }, + { + collapse: true, + remember: true + } + ); +}); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css deleted file mode 100644 index 049504af7..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-admin.css +++ /dev/null @@ -1,20 +0,0 @@ -.audit-trail-filter { - margin-bottom: 1em; -} - - .audit-trail-filter fieldset label { - display: inline-block; - width: 10em; - } - - .audit-trail-filter fieldset label.inline { - display: inline; - } - -.audit-trail-list .info { - line-height: 25px; -} - -.audit-trail-list .event-content .version { - font-size: 0.8em; -} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css new file mode 100644 index 000000000..ada6e9d79 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css @@ -0,0 +1,20 @@ +.audittrail-filter { + margin-bottom: 1em; +} + + .audittrail-filter fieldset label { + display: inline-block; + width: 10em; + } + + .audittrail-filter fieldset label.inline { + display: inline; + } + +.audittrail-event-metadata-section { + margin-bottom: 1em; +} + + .audittrail-event-metadata-section strong { + font-weight: bold; + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-part.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-part.css new file mode 100644 index 000000000..b72f55163 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-part.css @@ -0,0 +1,7 @@ +.audittrail-list-wrapper { + padding-top: 1em !important; +} + +.audittrail-list { + width: auto !important; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml index e94b9d225..f7201d498 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Detail.cshtml @@ -1,22 +1,18 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailDetailsViewModel @{ - Style.Include("audittrail-admin.css"); -} -@{ + Style.Include("audittrail-display.css"); + var record = Model.Record; var descriptor = Model.Descriptor; + + Layout.Title = T("Audit Trail Event"); } -
-
- @descriptor.Name - @descriptor.CategoryDescriptor.Name -
- @T("On: {0}", Display.DateTime(DateTimeUtc: record.CreatedUtc, CustomFormat: T("g"))) - @if (!String.IsNullOrWhiteSpace(record.UserName)) { - @T(" | ")@T("By: {0}", record.UserName) - } -
-
+ -
+
@Display(Model.DetailsShape)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index f61981d93..4879aff2c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -1,18 +1,18 @@ @using Orchard.AuditTrail.Services.Models @model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ - Style.Include("audittrail-admin.css"); + Style.Include("audittrail-display.css"); Style.Include("audittrail-grid.css"); var orderBy = Model.OrderBy; var orderByItems = new List { - new SelectListItem {Text = T("Date (desc)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, - new SelectListItem {Text = T("Category (asc)").Text, Value = AuditTrailOrderBy.CategoryAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.CategoryAscending}, - new SelectListItem {Text = T("Event (asc)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.EventAscending}, + new SelectListItem {Text = T("Date (newest first)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, + new SelectListItem {Text = T("Category (alphabetical)").Text, Value = AuditTrailOrderBy.CategoryAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.CategoryAscending}, + new SelectListItem {Text = T("Event name (alphabetical)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.EventAscending}, }; Layout.Title = T("Audit Trail"); } -
+
@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) {
@@ -24,7 +24,7 @@
@Display(Model.FilterLayout.TripleFirst)
- @Html.LabelFor(m => orderBy, T("Ordered by:")) + @Html.LabelFor(m => orderBy, T("Sort by:")) @Html.DropDownListFor(m => orderBy, orderByItems)
@@ -43,7 +43,7 @@
}
-
+
@if (!Model.Records.Any()) {

@T("There are no records to display.")

} @@ -56,7 +56,7 @@ @T("User") @T("Timestamp") @T("Comment") - @T("Event Data") + @T("Summary") diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index 6d77d88fe..f68bcfd2c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -5,6 +5,6 @@ var newRetentionPeriod = eventData.Get("NewRetentionPeriod"); } -
+
@T("Trimming retention period changed from {0} to {1}", oldRetentionPeriod, newRetentionPeriod) -
\ No newline at end of file +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index e24c42468..a3427afb5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -6,7 +6,8 @@ var contentItemVersionNumber = eventData.Get("VersionNumber"); } -
- @T("version {0}", contentItemVersionNumber)@T(" - ") - @title +
+ @T("Version {0}", contentItemVersionNumber) + @T(" - ") + @T("View")
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 365b4d52c..54a1ac76f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -3,45 +3,50 @@ @using Orchard.ContentManagement @{ var record = (AuditTrailEventRecord)Model.Record; - var contentItem = (ContentItem) Model.ContentItem; - var previousVersion = (ContentItem) Model.PreviousVersion; - var diffNodes = (IEnumerable) Model.DiffNodes; + var contentItem = (ContentItem)Model.ContentItem; + var previousVersion = (ContentItem)Model.PreviousVersion; + var diffNodes = (IEnumerable)Model.DiffNodes; } -
- @Html.ItemDisplayText(contentItem)@T(" - ")@contentItem.ContentType - @T("Version {0}", contentItem.Version) +
-@if (previousVersion != null) { - - - - - - - - - - - @if (!diffNodes.Any()) { + + +
+ @if (previousVersion != null) { +
@T("Diff Type")@T("Context")@T("Before")@T("After")
+ - + + + + - } - else { - foreach (var node in diffNodes) { + + + @if (!diffNodes.Any()) { - - - - + } - } - -
@T("")@T("Action")@T("Context")@T("Before")@T("After")
@T(node.Type.ToString())@node.Context@node.Previous@node.Current@T("")
- -} \ No newline at end of file + else { + foreach (var node in diffNodes) { + + @T(node.Type.ToString()) + @node.Context + @node.Previous + @node.Current + + } + } + + + } +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml index 9e6b51388..dedd7c64d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Created the {0} content part.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml index 9e6b51388..dedd7c64d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Created the {0} content part.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml index 6f61b5602..c9bb76bed 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml @@ -7,6 +7,6 @@ var contentDisplayName = eventData.Get("ContentDisplayName"); } -
+
@T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml index 6f61b5602..c9bb76bed 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml @@ -7,6 +7,6 @@ var contentDisplayName = eventData.Get("ContentDisplayName"); } -
+
@T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml index a88e8c570..eed00a730 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentFieldName = eventData.Get("ContentFieldName"); } -
+
@T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml index a88e8c570..eed00a730 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml @@ -5,6 +5,6 @@ var contentFieldName = eventData.Get("ContentFieldName"); } -
+
@T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml index efff40e3f..5edd0a3fb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentFieldName = eventData.Get("ContentFieldName"); } -
+
@T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml index efff40e3f..5edd0a3fb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml @@ -5,6 +5,6 @@ var contentFieldName = eventData.Get("ContentFieldName"); } -
+
@T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml index 6bd2ffc76..d22fcf49a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Settings for the {0} content part were updated.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index 6bd2ffc76..d22fcf49a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Settings for the {0} content part were updated.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml index e3b7718a1..167daf607 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Removed the {0} content part.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml index e3b7718a1..167daf607 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml @@ -4,6 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Removed the {0} content part.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml index 3a4e0ef90..80d4a2ca0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } -
+
@T("Created the {0} content type.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml index 3a4e0ef90..80d4a2ca0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml @@ -5,6 +5,6 @@ var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } -
+
@T("Created the {0} content type.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml index 5532bcf39..8bace8ba5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml index 5532bcf39..8bace8ba5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml index 137a210a0..3a0697226 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml index 137a210a0..3a0697226 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml index 364d52744..c9f146706 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index 364d52744..c9f146706 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -5,6 +5,6 @@ var contentPartName = eventData.Get("ContentPartName"); } -
+
@T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml index eb9545a7b..bdbbc7083 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } -
+
@T("Removed the {0} content type.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml index eb9545a7b..bdbbc7083 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml @@ -5,6 +5,6 @@ var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } -
+
@T("Removed the {0} content type.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index 1f6832afd..080f1f6e4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); } -
+
@T("Settings for the {0} content type were updated.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index 1f6832afd..080f1f6e4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -4,6 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); } -
+
@T("Settings for the {0} content type were updated.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml index 764446ae2..6d9b76ecc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var permissionName = eventData.Get("PermissionName"); } -
+
@T("Added the {0} permission to the {1} role.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml index 764446ae2..6d9b76ecc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml @@ -5,6 +5,6 @@ var permissionName = eventData.Get("PermissionName"); } -
+
@T("Added the {0} permission to the {1} role.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml index 870bf00f5..ffbc0bc40 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var permissionName = eventData.Get("PermissionName"); } -
+
@T("Removed the {0} permission from the {1} role.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml index 870bf00f5..ffbc0bc40 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml @@ -5,6 +5,6 @@ var permissionName = eventData.Get("PermissionName"); } -
+
@T("Removed the {0} permission from the {1} role.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml index 91d579147..29e31861f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var roleName = eventData.Get("RoleName"); } -
+
@T("Created {0} role.", roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml index 91d579147..29e31861f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml @@ -4,6 +4,6 @@ var roleName = eventData.Get("RoleName"); } -
+
@T("Created {0} role.", roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml index 8611bd024..769eabd6f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml @@ -5,6 +5,6 @@ var newRoleName = eventData.Get("NewRoleName"); } -
+
@T("Renamed {0} to {1}.", previousRoleName, newRoleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml index 8611bd024..769eabd6f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml @@ -5,6 +5,6 @@ var newRoleName = eventData.Get("NewRoleName"); } -
+
@T("Renamed {0} to {1}.", previousRoleName, newRoleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml index cc4093253..d59b373b9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml @@ -4,6 +4,6 @@ var userName = eventData.Get("UserName"); } -
+
@T("Attempted user name: {0}", userName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml index 5d64628ea..87e06a634 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml @@ -4,6 +4,6 @@ var userName = eventData.Get("UserName"); } -
+
@T("User: {0}", userName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml index 5d64628ea..87e06a634 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml @@ -4,6 +4,6 @@ var userName = eventData.Get("UserName"); } -
+
@T("User: {0}", userName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index 218ae43e9..aa62976e0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -1,61 +1,59 @@ @using Orchard.AuditTrail.Models @using Orchard.AuditTrail.ViewModels @{ + Style.Include("audittrail-part.css"); Script.Require("ShapesBase"); Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); - Script.Include("audittrail-admin.js").AtFoot(); + Script.Include("audittrail-expando.js").AtFoot(); } @{ var records = (IEnumerable)Model.Records; var auditTrailPart = (AuditTrailPart)Model.ContentPart; } @if (auditTrailPart.Id > 0) { - -
+
@T("Audit Trail") -
-
- @if (!records.Any()) { -

@T("There are no audit trail events to display.")

- } - else { - - +
+ @if (!records.Any()) { +

@T("There are no audit trail events to display.")

+ } + else { +
+ + + + + + + + + + + + + @foreach (var record in records) { - - - - - - - + + + + + + + - - - @foreach (var record in records) { - - - - - - - - - - } - - @if (Model.Pager.TotalItemCount > Model.Pager.PageSize) { - - - - - } -
@T("Event")@T("Category")@T("User")@T("Timestamp")@T("Comment")@T("Summary")
@T("Event")@T("Category")@T("User")@T("Timestamp")@T("Comment")@T("Event Data")@record.EventDescriptor.Name@record.CategoryDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment@Display(record.SummaryShape)@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
@record.EventDescriptor.Name@record.CategoryDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment@Display(record.SummaryShape)@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
- @Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { content = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null) -
- } -
-
+ + @if (Model.Pager.TotalItemCount > Model.Pager.PageSize) { + + + + @Html.ActionLink(T("Show more events").Text, "Index", "Admin", new { content = auditTrailPart.Id, page = 2, area = "Orchard.AuditTrail" }, null) + + + + } + + } +
} From c276433affcb26a63c92fd2ce333b30a0a94a18f Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 5 Jul 2014 19:27:37 +0200 Subject: [PATCH 054/116] Changed the column order of event records. --- .../Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml | 8 ++++---- .../Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index 4879aff2c..c2ace066d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -51,24 +51,24 @@ - + - + @foreach (var record in Model.Records) { - + - + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index aa62976e0..52aa592dc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -21,24 +21,24 @@
@T("Event") @T("Category")@T("Event") @T("User") @T("Timestamp")@T("Comment") @T("Summary")@T("Comment")
@record.EventDescriptor.Name @record.CategoryDescriptor.Name@record.EventDescriptor.Name @record.Record.UserName @Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment @Display(record.SummaryShape)@record.Record.Comment @Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
- + - + @foreach (var record in records) { - + - + } From d3481053d98af63dcfa1aba52af53b0840186e0b Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 14:46:31 +0200 Subject: [PATCH 055/116] Redesigned the audit trail filtering UI. --- .../Controllers/AdminController.cs | 4 +- .../Orchard.AuditTrail.csproj | 5 +- .../Content/ContentAuditTrailEventProvider.cs | 8 +- .../ContentTypeAuditTrailEventProvider.cs | 2 +- .../Services/AuditTrailManager.cs | 16 +- .../Services/CommonAuditTrailEventHandler.cs | 12 +- .../Services/IAuditTrailManager.cs | 2 +- .../Services/Models/DisplayFilterContext.cs | 6 +- .../Shapes/AuditTrailShapes.cs | 17 +- .../Styles/audittrail-display.css | 33 +- .../Styles/audittrail-grid.css | 285 ------------------ .../ViewModels/AuditTrailViewModel.cs | 2 +- .../Views/Admin/Index.cshtml | 45 +-- .../AuditTrailFilter-Common-Category.cshtml | 6 +- .../AuditTrailFilter-Common-Date-From.cshtml | 6 + .../AuditTrailFilter-Common-Date-To.cshtml | 6 + .../Views/AuditTrailFilter-Common-Date.cshtml | 11 - .../Views/AuditTrailFilter-Common-User.cshtml | 6 +- .../Views/AuditTrailFilter-ContentItem.cshtml | 10 +- .../Views/AuditTrailFilter-ContentType.cshtml | 6 +- .../Views/AuditTrailFilter.cshtml | 7 + .../Themes/TheAdmin/Styles/site.css | 8 +- 22 files changed, 98 insertions(+), 405 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 62562006f..e192d0fb7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -34,7 +34,7 @@ namespace Orchard.AuditTrail.Controllers { var filters = Filters.From(Request.QueryString); var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, filters, orderBy ?? AuditTrailOrderBy.DateDescending); var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var filterLayout = _auditTrailManager.BuildFilterDisplays(filters); + var filterDisplay = _auditTrailManager.BuildFilterDisplay(filters); var eventDescriptorsQuery = from c in _auditTrailManager.DescribeCategories() from e in c.Events @@ -55,7 +55,7 @@ namespace Orchard.AuditTrail.Controllers { Records = recordViewModelsQuery.ToArray(), Pager = pagerShape, OrderBy = orderBy ?? AuditTrailOrderBy.DateDescending, - FilterLayout = filterLayout + FilterDisplay = filterDisplay }; return View(viewModel); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 845d40c91..baee17a45 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -85,7 +85,6 @@ - @@ -135,13 +134,15 @@ - + Code + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs index 1624e54de..d0f507e0b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs @@ -46,10 +46,12 @@ namespace Orchard.AuditTrail.Providers.Content { private void DisplayFilter(DisplayFilterContext context) { var contentItemId = context.Filters.Get("content").ToInt32(); - var contentItem = contentItemId != null ? _contentManager.Get(contentItemId.Value, VersionOptions.Latest) : default(ContentItem); - var filterDisplay = context.ShapeFactory.AuditTrailFilter__ContentItem(ContentItem: contentItem); + if (contentItemId != null) { + var contentItem = contentItemId != null ? _contentManager.Get(contentItemId.Value, VersionOptions.Latest) : default(ContentItem); + var filterDisplay = context.ShapeFactory.AuditTrailFilter__ContentItem(ContentItem: contentItem); - context.FilterLayout.TripleSecond.Add(filterDisplay); + context.FilterDisplay.Add(filterDisplay); + } } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 67196735d..6761a90ba 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -49,7 +49,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { ContentType: context.Filters.Get("contenttype"), ContentTypes: _contentDefinitionManager.ListTypeDefinitions().OrderBy(x => x.DisplayName).ToArray()); - context.FilterLayout.TripleFirst.Add(filterDisplay); + context.FilterDisplay.Add(filterDisplay); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index f5f3f6ce8..d22a33f66 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -98,25 +98,21 @@ namespace Orchard.AuditTrail.Services { return _auditTrailRepository.Get(id); } - public dynamic BuildFilterDisplays(Filters filters) { - var layout = (dynamic)_shapeFactory.Create("AuditTrailFilters", Arguments.From(new { - TripleFirst = _shapeFactory.Create("AuditTrailFilters_TripleFirst"), - TripleSecond = _shapeFactory.Create("AuditTrailFilters_TripleSecond"), - TripleThird = _shapeFactory.Create("AuditTrailFilters_TripleThird") - })); - var displayContext = new DisplayFilterContext(_shapeFactory, filters, layout); + public dynamic BuildFilterDisplay(Filters filters) { + var filterDisplay = (dynamic)_shapeFactory.Create("AuditTrailFilter"); + var filterDisplayContext = new DisplayFilterContext(_shapeFactory, filters, filterDisplay); // Invoke event handlers. - _auditTrailEventHandlers.DisplayFilter(displayContext); + _auditTrailEventHandlers.DisplayFilter(filterDisplayContext); // Give each provider a chance to provide a filter display. var providersContext = DescribeProviders(); foreach (var action in providersContext.FilterDisplays) { - action(displayContext); + action(filterDisplayContext); } - return layout; + return filterDisplay; } public AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs index e43c734ae..cc082cdca 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs @@ -42,16 +42,16 @@ namespace Orchard.AuditTrail.Services { var toDate = context.Filters.Get("to.Date"); var category = context.Filters.Get("category"); var userNameFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__User(UserName: userName); - var dateFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Date( - From: new DateTimeEditor {Date = fromDate, ShowDate = true}, - To: new DateTimeEditor {Date = toDate, ShowDate = true}); + var dateFromFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Date__From(Editor: new DateTimeEditor {Date = fromDate, ShowDate = true}); + var dateToFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Date__To(Editor: new DateTimeEditor { Date = toDate, ShowDate = true }); var categoryFilterDisplay = context.ShapeFactory.AuditTrailFilter__Common__Category( Categories: _auditTrailManager.Value.DescribeCategories().ToArray(), Category: category); - context.FilterLayout.TripleFirst.Add(dateFilterDisplay); - context.FilterLayout.TripleFirst.Add(categoryFilterDisplay); - context.FilterLayout.TripleSecond.Add(userNameFilterDisplay); + context.FilterDisplay.Add(dateFromFilterDisplay); + context.FilterDisplay.Add(dateToFilterDisplay); + context.FilterDisplay.Add(categoryFilterDisplay); + context.FilterDisplay.Add(userNameFilterDisplay); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 031c0ea47..94ca56f4a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -29,7 +29,7 @@ namespace Orchard.AuditTrail.Services { /// /// Input for each filter builder. /// A tree of shapes. - dynamic BuildFilterDisplays(Filters filters); + dynamic BuildFilterDisplay(Filters filters); /// /// Records an audit trail event. diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs index 7f463d7eb..5d9859c83 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DisplayFilterContext.cs @@ -2,14 +2,14 @@ using Orchard.DisplayManagement; namespace Orchard.AuditTrail.Services.Models { public class DisplayFilterContext { - public DisplayFilterContext(IShapeFactory shapeFactory, Filters filters, dynamic filterLayout) { + public DisplayFilterContext(IShapeFactory shapeFactory, Filters filters, dynamic filterDisplay) { ShapeFactory = shapeFactory; Filters = filters; - FilterLayout = filterLayout; + FilterDisplay = filterDisplay; } public dynamic ShapeFactory { get; set; } public Filters Filters { get; set; } - public dynamic FilterLayout { get; set; } + public dynamic FilterDisplay { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs index 6f6a085a8..2e4722f79 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs @@ -4,22 +4,7 @@ using Orchard.DisplayManagement; namespace Orchard.AuditTrail.Shapes { public class AuditTrailShapes : IDependency { [Shape] - public void AuditTrailFilters(dynamic Shape, dynamic Display, TextWriter Output) { - DispayChildren(Shape, Display, Output); - } - - [Shape] - public void AuditTrailFilters_TripleFirst(dynamic Shape, dynamic Display, TextWriter Output) { - DispayChildren(Shape, Display, Output); - } - - [Shape] - public void AuditTrailFilters_TripleSecond(dynamic Shape, dynamic Display, TextWriter Output) { - DispayChildren(Shape, Display, Output); - } - - [Shape] - public void AuditTrailFilters_TripleThird(dynamic Shape, dynamic Display, TextWriter Output) { + public void AuditTrailFilterDisplay(dynamic Shape, dynamic Display, TextWriter Output) { DispayChildren(Shape, Display, Output); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css index ada6e9d79..82253eb60 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css @@ -1,20 +1,35 @@ -.audittrail-filter { + +.audittrail-filter-section { + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + justify-content: flex-start; + align-items: flex-end; + align-content: flex-end; margin-bottom: 1em; + border: 1px solid #eaeaea; + background: #f5f5f5; + padding: 4px 10px 3px; } - .audittrail-filter fieldset label { - display: inline-block; - width: 10em; - } +.filter-control-group { + margin-right: 10px; + margin-bottom: 6px; +} - .audittrail-filter fieldset label.inline { - display: inline; - } +.filter-control-group label { + padding-bottom: 0; +} + +.filter-control-group select { + padding-top: 2px !important; + padding-bottom: 2px !important; +} .audittrail-event-metadata-section { margin-bottom: 1em; } .audittrail-event-metadata-section strong { - font-weight: bold; + /*font-weight: bold;*/ } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css deleted file mode 100644 index eae79aeb2..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-grid.css +++ /dev/null @@ -1,285 +0,0 @@ -.table, .row, .cell { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - - .table > .row { - width: 100%; - } - - .table.fixed > .row { - margin-left: auto; - margin-right: auto; - } - -.row { - display: block; - margin: 0 0 20px 0; -} - - .row:after { - content: ""; - display: table; - clear: both; - } - -.cell { - display: block; - float: left; - padding-right: 10px; - padding-left: 10px; -} - -.row > .cell:last-of-type { - padding-right: 0; -} - -.row > .cell:first-of-type { - padding-left: 0; -} - -/* Opt-in outside padding */ -.row-pad { - padding: 20px 0 20px 20px; -} - - .row-pad .cell:last-of-type { - padding-right: 20px; - } - -.span-1-1 { - width: 100%; -} - -.span-1-2 { - width: 50%; -} - -.span-1-3 { - width: 33.33%; -} - -.span-1-4 { - width: 25%; -} - -.span-1-5 { - width: 20%; -} - -.span-1-6 { - width: 16.66%; -} - -.span-1-7 { - width: 14.28%; -} - -.span-1-8 { - width: 12.5%; -} - -.span-1-9 { - width: 11.11%; -} - -.span-1-10 { - width: 10%; -} - -.span-1-11 { - width: 9.09%; -} - -.span-1-12 { - width: 8.33%; -} - -.span-2-3 { - width: 66.66%; -} - -.span-2-4 { - width: 50%; -} - -.span-2-5 { - width: 40%; -} - -.span-2-6 { - width: 33.33%; -} - -.span-2-8 { - width: 25%; -} - -.span-2-10 { - width: 20%; -} - -.span-2-12 { - width: 16.66%; -} - -.span-3-4 { - width: 75%; -} - -.span-3-5 { - width: 60%; -} - -.span-3-6 { - width: 50%; -} - -.span-3-8 { - width: 37.5%; -} - -.span-3-10 { - width: 33.33%; -} - -.span-3-12 { - width: 25%; -} - -.span-4-5 { - width: 80%; -} - -.span-4-6 { - width: 66.66%; -} - -.span-4-8 { - width: 50%; -} - -.span-4-10 { - width: 40%; -} - -.span-4-12 { - width: 33.33%; -} - -.span-5-6 { - width: 83.33%; -} - -.span-5-8 { - width: 75%; -} - -.span-5-10 { - width: 50%; -} - -.span-5-12 { - width: 41.66%; -} - -.span-6-8 { - width: 75%; -} - -.span-6-10 { - width: 60%; -} - -.span-6-12 { - width: 50%; -} - -.span-7-8 { - width: 87.5%; -} - -.span-7-10 { - width: 70%; -} - -.span-7-12 { - width: 58.33%; -} - -.span-8-10 { - width: 80%; -} - -.span-8-12 { - width: 66.66%; -} - -.span-9-10 { - width: 90%; -} - -.span-9-12 { - width: 75%; -} - -.span-10-12 { - width: 83.33%; -} - -.span-11-12 { - width: 91.66%; -} - -/* Bootstrap compatible spans */ -.span-1 { width: 8.33%; } -.span-2 { width: 16.66%; } -.span-3 { width: 25%; } -.span-4 { width: 33.33%; } -.span-5 { width: 41.66%; } -.span-6 { width: 50%; } -.span-7 { width: 58.33%; } -.span-8 { width: 66.66%; } -.span-9 { width: 75%; } -.span-10 { width: 83.33%; } -.span-11 { width: 91.66%; } -.span-12 { width: 100%; } - - -/* RESPONSIVENESS */ - -/* Large desktop */ -@media (min-width: 1200px) { - .table.fixed > .row { - width: 1170px; - } -} - -/* Default */ -@media (min-width: 980px) and (max-width: 1199px) { - .table.fixed > .row { - width: 960px; - } -} - -/* Portrait tablet to landscape and desktop */ -@media (min-width: 768px) and (max-width: 979px) { - .table.fixed > .row { - width: 724px; - } -} - -/* Landscape phone to portrait tablet */ -@media (max-width: 767px) { - .table.fixed > .row { - width: 100%; - } -} - -/* Landscape phones and down */ -@media (max-width: 480px) { - .table.fixed > .row { - width: 100%; - } -} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs index dfbdac2e1..9f4a6ba09 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailViewModel.cs @@ -3,7 +3,7 @@ using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailViewModel { - public dynamic FilterLayout { get; set; } + public dynamic FilterDisplay { get; set; } public AuditTrailOrderBy OrderBy { get; set; } public IEnumerable Records { get; set; } public dynamic List { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index c2ace066d..6ca727378 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -2,48 +2,29 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailViewModel @{ Style.Include("audittrail-display.css"); - Style.Include("audittrail-grid.css"); + var orderBy = Model.OrderBy; var orderByItems = new List { new SelectListItem {Text = T("Date (newest first)").Text, Value = AuditTrailOrderBy.DateDescending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.DateDescending}, new SelectListItem {Text = T("Category (alphabetical)").Text, Value = AuditTrailOrderBy.CategoryAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.CategoryAscending}, new SelectListItem {Text = T("Event name (alphabetical)").Text, Value = AuditTrailOrderBy.EventAscending.ToString(), Selected = Model.OrderBy == AuditTrailOrderBy.EventAscending}, }; - + Layout.Title = T("Audit Trail"); } -
- @using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { -
-
-
- @Display(Model.FilterLayout) -
-
-
-
- @Display(Model.FilterLayout.TripleFirst) -
- @Html.LabelFor(m => orderBy, T("Sort by:")) - @Html.DropDownListFor(m => orderBy, orderByItems) -
-
-
- @Display(Model.FilterLayout.TripleSecond) -
-
- @Display(Model.FilterLayout.TripleThird) -
-
-
-
- -
-
+@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { +
+ @Display(Model.FilterDisplay) +
+ @Html.LabelFor(m => orderBy, T("Sort by:")) + @Html.DropDownListFor(m => orderBy, orderByItems) +
+
+
- }
-
+} +
@if (!Model.Records.Any()) {

@T("There are no records to display.")

} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml index 8a304ae91..639d1b5dd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Category.cshtml @@ -4,7 +4,5 @@ var currentCategory = (string)Model.Category; var listItems = categories.Select(x => new SelectListItem { Text = x.Name.Text, Value = x.Category, Selected = x.Category == currentCategory }); } -
- @Html.Label("category", T("Category:").Text) - @Html.DropDownList("category", listItems, "") -
\ No newline at end of file +@Html.Label("category", T("Category:").Text) +@Html.DropDownList("category", listItems, "") diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml new file mode 100644 index 000000000..a97c78674 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml @@ -0,0 +1,6 @@ +@using Orchard.Core.Common.ViewModels +@{ + var editor = (DateTimeEditor)Model.Editor; +} +@Html.Label("from.Date", T("From:").Text) +@Html.EditorFor(m => editor) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml new file mode 100644 index 000000000..d61f4593d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml @@ -0,0 +1,6 @@ +@using Orchard.Core.Common.ViewModels +@{ + var editor = (DateTimeEditor)Model.Editor; +} +@Html.Label("to.Date", T("To:").Text) +@Html.EditorFor(m => editor) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml deleted file mode 100644 index 4a908da34..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date.cshtml +++ /dev/null @@ -1,11 +0,0 @@ -@using Orchard.Core.Common.ViewModels -@{ - var from = (DateTimeEditor)Model.From; - var to = (DateTimeEditor)Model.To; -} -
- @Html.Label("from.Date", T("From:").Text) - @Html.EditorFor(m => from) - @Html.Label("to.Date", T("To:").Text, new { @class = "inline" }) - @Html.EditorFor(m => to) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml index e36a07db8..723be7852 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-User.cshtml @@ -1,4 +1,2 @@ -
- @Html.Label("username", T("User:").Text) - @Html.TextBox("username", (string)Model.UserName, new { @class = "text" }) -
\ No newline at end of file +@Html.Label("username", T("User:").Text) +@Html.TextBox("username", (string)Model.UserName, new { @class = "text" }) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml index b4d11d460..f059affae 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentItem.cshtml @@ -2,10 +2,6 @@ @{ var contentItem = (ContentItem)Model.ContentItem; } -@if (contentItem != null) { -
- @Html.Label("contentitem", T("Content Item:").Text) - @Html.ItemEditLink(contentItem) - @Html.Hidden("content", contentItem.Id) -
-} \ No newline at end of file +@Html.Label("contentitem", T("Content Item:").Text) +@Html.TextBox("contentitemname", Html.ItemDisplayText(contentItem), new { @class = "text", disabled = "disabled"}) +@Html.Hidden("content", contentItem.Id) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml index 06a019262..9fdb0f3fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-ContentType.cshtml @@ -4,7 +4,5 @@ var currentContentType = (string)Model.ContentType; var listItems = contentTypes.Select(x => new SelectListItem {Text = x.DisplayName, Value = x.Name, Selected = x.Name == currentContentType}); } -
- @Html.Label("contenttype", T("Content type:").Text) - @Html.DropDownList("contenttype", listItems, "") -
\ No newline at end of file +@Html.Label("contenttype", T("Content type:").Text) +@Html.DropDownList("contenttype", listItems, "") diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml new file mode 100644 index 000000000..04a81505b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml @@ -0,0 +1,7 @@ +@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { + foreach (var item in Model) { +
+ @Display(item) +
+ } +} diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css index 80ee264f5..c916c60d7 100644 --- a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css +++ b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css @@ -526,14 +526,14 @@ span.message { color:#fff; } .info { - background: url(images/info.gif) no-repeat 5px 5px #fff; + background: url(images/info.gif) no-repeat 6px 6px #fff; border:1px solid #e4e8ee; /* blue */ - padding-left:26px; + padding:4px 4px 4px 26px; } .error { - background: url(images/error.gif) no-repeat 5px 5px #fff; + background: url(images/error.gif) no-repeat 6px 6px #fff; border:1px solid #e5cece; /* red */ - padding-left:26px; + padding-left:4px 4px 4px 26px; } .message-Information, .notifications { background:#e6f1c9; /* green */ From ac6b3b2f66665214354f9e751aa1f19eec13d1f7 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 17:42:06 +0200 Subject: [PATCH 056/116] Completed extraction of roles and users audit trail providers into separate features by removing duplicated interfaces. Renamed some helper classes as extensions. Some minor reformating and naming changes. Fixed bugs in the role audit trail provider. --- .../Drivers/AuditTrailSettingsPartDriver.cs | 35 +++++++++++-------- ...ateTimeHelper.cs => DateTimeExtensions.cs} | 2 +- ...ntDataHelper.cs => EventDataExtensions.cs} | 2 +- ...ntNameHelper.cs => EventNameExtensions.cs} | 2 +- ...{FiltersHelper.cs => FiltersExtensions.cs} | 2 +- ...onversionHelper.cs => StringExtensions.cs} | 2 +- .../Orchard.AuditTrail.csproj | 20 +++++++---- .../Providers/Content/DiffGramAnalyzer.cs | 6 ++-- .../Providers/Content/IDiffGramAnalyzer.cs | 4 +-- .../Providers/Roles/IRoleEventHandler.cs | 13 ------- .../Providers/Roles/RoleEventHandler.cs | 29 +++++++-------- .../Providers/Users/IUserEventHandler.cs | 27 -------------- .../Providers/Users/UserEventHandler.cs | 22 ++++++++++++ .../Services/AuditTrailManager.cs | 2 +- .../Services/Models/DescribeFor.cs | 2 +- .../AuditTrailCategorySettingsViewModel.cs | 2 +- 16 files changed, 82 insertions(+), 90 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/{DateTimeHelper.cs => DateTimeExtensions.cs} (92%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/{EventDataHelper.cs => EventDataExtensions.cs} (89%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/{EventNameHelper.cs => EventNameExtensions.cs} (90%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/{FiltersHelper.cs => FiltersExtensions.cs} (86%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/{StringConversionHelper.cs => StringExtensions.cs} (86%) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index da3fa20c1..97e21bc3e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -27,22 +27,26 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailSettings_Edit", () => { var descriptors = _auditTrailManager.DescribeCategories(); var eventSettings = part.EventSettings.ToList(); + var categoriesQuery = + from categoryDescriptor in descriptors + let eventsQuery = + from eventDescriptor in categoryDescriptor.Events + let eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventDescriptor.Event) + select new AuditTrailEventSettingsViewModel { + Event = eventDescriptor.Event, + Name = eventDescriptor.Name, + Description = eventDescriptor.Description, + IsEnabled = eventDescriptor.IsMandatory || (eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault), + IsMandatory = eventDescriptor.IsMandatory + } + select new AuditTrailCategorySettingsViewModel { + Category = categoryDescriptor.Category, + Name = categoryDescriptor.Name, + Events = eventsQuery.ToArray() + }; + var viewModel = new AuditTrailSettingsViewModel { - Categories = (from categoryDescriptor in descriptors - select new AuditTrailCategorySettingsViewModel { - Category = categoryDescriptor.Category, - Name = categoryDescriptor.Name, - Events = - (from eventDescriptor in categoryDescriptor.Events - let eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventDescriptor.Event) - select new AuditTrailEventSettingsViewModel { - Event = eventDescriptor.Event, - Name = eventDescriptor.Name, - Description = eventDescriptor.Description, - IsEnabled = eventDescriptor.IsMandatory || (eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault), - IsMandatory = eventDescriptor.IsMandatory - }).ToList() - }).ToList() + Categories = categoriesQuery.ToArray() }; if (updater != null) { @@ -55,6 +59,7 @@ namespace Orchard.AuditTrail.Drivers { eventSettings.Add(eventSetting); } + // TODO: Security hole! IsMandatory could be spoofed in the request! eventSetting.IsEnabled = eventSettingViewModel.IsEnabled || eventSettingViewModel.IsMandatory; } part.EventSettings = eventSettings; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs similarity index 92% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs index 0b9e0a349..0289ca343 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs @@ -1,7 +1,7 @@ using System; namespace Orchard.AuditTrail.Helpers { - public static class DateTimeHelper { + public static class DateTimeExtensions { public static DateTime? Earliest(this DateTime? value) { if (value == null) return null; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataExtensions.cs similarity index 89% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataExtensions.cs index 664af226a..27c66302b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventDataExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; namespace Orchard.AuditTrail.Helpers { - public static class EventDataHelper { + public static class EventDataExtensions { public static T Get(this IDictionary eventData, string key) { if (eventData == null || !eventData.ContainsKey(key)) return default(T); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs similarity index 90% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs index 64702e7ad..5302a8fa3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs @@ -2,7 +2,7 @@ using Orchard.AuditTrail.Services; namespace Orchard.AuditTrail.Helpers { - internal static class EventNameHelper { + internal static class EventNameExtensions { public static string GetFullyQualifiedEventName(string eventName) where T : IAuditTrailEventProvider { return GetFullyQualifiedEventName(typeof(T), eventName); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersExtensions.cs similarity index 86% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersExtensions.cs index 04c7912dc..6dd2e1067 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/FiltersExtensions.cs @@ -1,7 +1,7 @@ using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Helpers { - public static class FiltersHelper { + public static class FiltersExtensions { public static string Get(this Filters filters, string key) { if (!filters.ContainsKey(key)) return null; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs similarity index 86% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs index f3f2b40db..224c17986 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringConversionHelper.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs @@ -1,7 +1,7 @@ using System; namespace Orchard.AuditTrail.Helpers { - public static class StringConversionHelper { + public static class StringExtensions { public static int? ToInt32(this string value) { if (String.IsNullOrWhiteSpace(value)) return null; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index baee17a45..3ec3e3a6b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -161,6 +161,14 @@ {fe5c5947-d2d5-42c5-992a-13d672946135} Orchard.ImportExport + + {d10ad48f-407d-4db5-a328-173ec7cb010f} + Orchard.Roles + + + {79aed36e-abd0-4747-93d3-8722b042454b} + Orchard.Users + @@ -169,9 +177,9 @@ - - - + + + @@ -206,19 +214,17 @@ - + - - - + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index 5e5989b91..5eb08b657 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -8,13 +8,11 @@ using Microsoft.XmlDiffPatch; namespace Orchard.AuditTrail.Providers.Content { public class DiffGramAnalyzer : IDiffGramAnalyzer { public XElement GenerateDiffGram(XElement element1, XElement element2) { - using(var node1Reader = element1.CreateReader()) + using (var node1Reader = element1.CreateReader()) using (var node2Reader = element2.CreateReader()) { var result = new XDocument(); using (var writer = result.CreateWriter()) { - var diff = - new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreWhitespace | - XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreXmlDecl); + var diff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreWhitespace | XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreXmlDecl); diff.Compare(node1Reader, node2Reader, writer); writer.Flush(); writer.Close(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs index 7482dd681..82631d36c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/IDiffGramAnalyzer.cs @@ -9,8 +9,8 @@ namespace Orchard.AuditTrail.Providers.Content { XElement GenerateDiffGram(XElement element1, XElement element2); /// - /// Analyzes the specified DiffGram against the specified original XML element and returns a list of diff nodes, - /// where each node describes the difference between the original and updated document. + /// Analyzes the specified DiffGram element against the specified original XML element and returns a list of diff nodes, + /// where each node describes a difference between the original and updated document. /// IEnumerable Analyze(XElement original, XElement diffGram); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs deleted file mode 100644 index ddef5f9c0..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/IRoleEventHandler.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Orchard.Events; - -namespace Orchard.AuditTrail.Providers.Roles { - public interface IRoleEventHandler : IEventHandler { - void Created(dynamic context); - void Removed(dynamic context); - void Renamed(dynamic context); - void PermissionAdded(dynamic context); - void PermissionRemoved(dynamic context); - void UserAdded(dynamic context); - void UserRemoved(dynamic context); - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs index b63179143..49d040998 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Orchard.AuditTrail.Services; using Orchard.Environment.Extensions; +using Orchard.Roles.Events; using Orchard.Security; namespace Orchard.AuditTrail.Providers.Roles { @@ -14,38 +15,38 @@ namespace Orchard.AuditTrail.Providers.Roles { _wca = wca; } - public void Created(dynamic context) { + public void Created(RoleCreatedContext context) { RecordAuditTrailEvent(RoleAuditTrailEventProvider.Created, context.Role.Name); } - public void Removed(dynamic context) { + public void Removed(RoleRemovedContext context) { RecordAuditTrailEvent(RoleAuditTrailEventProvider.Removed, context.Role.Name); } - public void Renamed(dynamic context) { + public void Renamed(RoleRenamedContext context) { var eventData = new Dictionary { - {"RoleName", (string)context.Role.Name}, - {"PreviousRoleName", (string)context.PreviousRoleName}, - {"NewRoleName", (string)context.NewRoleName}, + {"RoleName", context.Role.Name}, + {"PreviousRoleName", context.PreviousRoleName}, + {"NewRoleName", context.NewRoleName}, }; RecordAuditTrailEvent(RoleAuditTrailEventProvider.Renamed, context.Role.Name, properties: null, eventData:eventData); } - public void PermissionAdded(dynamic context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionAdded, (string) context.Role.Name, (IUser) context.Permission.Name); + public void PermissionAdded(PermissionAddedContext context) { + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionAdded, context.Role.Name); } - public void PermissionRemoved(dynamic context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionRemoved, (string) context.Role.Name, (IUser) context.Permission.Name); + public void PermissionRemoved(PermissionRemovedContext context) { + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionRemoved, context.Role.Name); } - public void UserAdded(dynamic context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserAdded, (string) context.Role.Name, (IUser) context.User); + public void UserAdded(UserAddedContext context) { + RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserAdded, context.Role.Name, context.User); } - public void UserRemoved(dynamic context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserRemoved, (string) context.Role.Name, (IUser) context.User); + public void UserRemoved(UserRemovedContext context) { + RecordAuditTrailEvent(RoleAuditTrailEventProvider.UserRemoved, context.Role.Name, context.User); } private void RecordAuditTrailEvent(string eventName, string roleName) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs deleted file mode 100644 index 2b3342eb5..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/IUserEventHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Orchard.Events; -using Orchard.Security; - -namespace Orchard.AuditTrail.Providers.Users { - public interface IUserEventHandler : IEventHandler { - - /// - /// Called after a user has logged in. - /// - void LoggedIn(IUser user); - - /// - /// Called when a user explicitly logs out (as opposed to one whose session cookie simply expires). - /// - void LoggedOut(IUser user); - - /// - /// Called when a login attempt failed. - /// - void LogInFailed(string userNameOrEmail, string password); - - /// - /// Called after a user has changed password. - /// - void ChangedPassword(IUser user); - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs index 449cd626c..61e6d1b95 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Users/UserEventHandler.cs @@ -2,6 +2,7 @@ using Orchard.AuditTrail.Services; using Orchard.Environment.Extensions; using Orchard.Security; +using Orchard.Users.Events; namespace Orchard.AuditTrail.Providers.Users { [OrchardFeature("Orchard.AuditTrail.Users")] @@ -47,5 +48,26 @@ namespace Orchard.AuditTrail.Providers.Users { _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties, eventData, eventFilterKey: "user", eventFilterData: user.UserName); } + + public void Creating(UserContext context) { + } + + public void Created(UserContext context) { + } + + public void LoggingIn(string userNameOrEmail, string password) { + } + + public void AccessDenied(IUser user) { + } + + public void SentChallengeEmail(IUser user) { + } + + public void ConfirmedEmail(IUser user) { + } + + public void Approved(IUser user) { + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index d22a33f66..d05bd1a8f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -179,7 +179,7 @@ namespace Orchard.AuditTrail.Services { } public AuditTrailEventDescriptor DescribeEvent(string eventName) where T:IAuditTrailEventProvider { - var fullyQualifiedEventName = EventNameHelper.GetFullyQualifiedEventName(eventName); + var fullyQualifiedEventName = EventNameExtensions.GetFullyQualifiedEventName(eventName); return DescribeEvent(fullyQualifiedEventName); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs index 7d360a0a9..fed7d2aa4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs @@ -32,7 +32,7 @@ namespace Orchard.AuditTrail.Services.Models { Name = Name, Events = Events }, - Event = EventNameHelper.GetFullyQualifiedEventName(provider.GetType(), eventName), + Event = EventNameExtensions.GetFullyQualifiedEventName(provider.GetType(), eventName), Name = name, Description = description, IsEnabledByDefault = enableByDefault, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs index 04d619a08..81267c677 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs @@ -5,6 +5,6 @@ namespace Orchard.AuditTrail.ViewModels { public class AuditTrailCategorySettingsViewModel { public string Category { get; set; } public LocalizedString Name { get; set; } - public IList Events { get; set; } + public IEnumerable Events { get; set; } } } \ No newline at end of file From ff9a380ef5603745a25fb4864e2d3f39332ac1cf Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 18:07:08 +0200 Subject: [PATCH 057/116] Some more minor renames and reformatting. --- .../Modules/Orchard.AuditTrail/Permissions.cs | 2 +- .../Services/AuditTrailEventDisplayBuilder.cs | 6 +-- .../Services/AuditTrailManager.cs | 39 ++++++++++--------- .../AuditTrailTrimmingBackgroundTask.cs | 11 +++--- .../Services/CommonAuditTrailEventHandler.cs | 18 ++++++--- .../Services/IAuditTrailManager.cs | 6 +-- .../Models/AuditTrailEventDescriptor.cs | 4 -- .../Services/Models/DescribeFor.cs | 1 + 8 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs index 2fd175e1e..1438e0d98 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs @@ -4,7 +4,7 @@ using Orchard.Security.Permissions; namespace Orchard.AuditTrail { public class Permissions : IPermissionProvider { - public static readonly Permission ViewAuditTrail = new Permission { Description = "View Audit Trail", Name = "ViewAuditTrail" }; + public static readonly Permission ViewAuditTrail = new Permission { Description = "View audit trail", Name = "ViewAuditTrail" }; public static readonly Permission ManageAuditTrailSettings = new Permission { Description = "Manage audit trail settings", Name = "ManageAuditTrailSettings" }; public virtual Feature Feature { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs index 643efe12e..8dcb8ca8a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -25,12 +25,12 @@ namespace Orchard.AuditTrail.Services { metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}__{1}", record.Category, GetShortName(record.Event))); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, GetShortName(record.Event))); + metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}__{1}", record.Category, GetShortEventName(record.Event))); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, GetShortEventName(record.Event))); return auditTrailEventShape; } - private string GetShortName(string fullyQualifiedEventName) { + private string GetShortEventName(string fullyQualifiedEventName) { var index = fullyQualifiedEventName.LastIndexOf('.') + 1; return fullyQualifiedEventName.Substring(index); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index d05bd1a8f..249460a5b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -27,13 +27,13 @@ namespace Orchard.AuditTrail.Services { public AuditTrailManager( IRepository auditTrailRepository, - IAuditTrailEventProvider providers, + IAuditTrailEventProvider providers, IClock clock, - IAuditTrailEventHandler auditTrailEventHandlers, - IEventDataSerializer serializer, - ICacheManager cacheManager, - ISiteService siteService, - ISignals signals, + IAuditTrailEventHandler auditTrailEventHandlers, + IEventDataSerializer serializer, + ICacheManager cacheManager, + ISiteService siteService, + ISignals signals, IShapeFactory shapeFactory) { _auditTrailRepository = auditTrailRepository; @@ -48,13 +48,13 @@ namespace Orchard.AuditTrail.Services { } public IPageOfItems GetRecords( - int page, - int pageSize, - Filters filters = null, + int page, + int pageSize, + Filters filters = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending) { - + var query = _auditTrailRepository.Table; - + if (filters != null) { var filterContext = new QueryFilterContext(query, filters); @@ -115,9 +115,9 @@ namespace Orchard.AuditTrail.Services { return filterDisplay; } - public AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T:IAuditTrailEventProvider { + public AuditTrailEventRecordResult CreateRecord(string eventName, IUser user, IDictionary properties = null, IDictionary eventData = null, string eventFilterKey = null, string eventFilterData = null) where T : IAuditTrailEventProvider { var eventDescriptor = DescribeEvent(eventName); - if(!IsEventEnabled(eventDescriptor)) + if (!IsEventEnabled(eventDescriptor)) return new AuditTrailEventRecordResult { Record = null, IsDisabled = true @@ -156,7 +156,7 @@ namespace Orchard.AuditTrail.Services { } private bool IsEventEnabled(AuditTrailEventDescriptor eventDescriptor) { - if(eventDescriptor.IsMandatory) + if (eventDescriptor.IsMandatory) return true; var settingsDictionary = _cacheManager.Get("AuditTrail.EventSettings", context => { @@ -178,17 +178,18 @@ namespace Orchard.AuditTrail.Services { return context; } - public AuditTrailEventDescriptor DescribeEvent(string eventName) where T:IAuditTrailEventProvider { + public AuditTrailEventDescriptor DescribeEvent(string eventName) where T : IAuditTrailEventProvider { var fullyQualifiedEventName = EventNameExtensions.GetFullyQualifiedEventName(eventName); return DescribeEvent(fullyQualifiedEventName); } public AuditTrailEventDescriptor DescribeEvent(string fullyQualifiedEventName) { var categoryDescriptors = DescribeCategories(); - var eventDescriptorQuery = from c in categoryDescriptors - from e in c.Events - where e.Event == fullyQualifiedEventName - select e; + var eventDescriptorQuery = + from c in categoryDescriptors + from e in c.Events + where e.Event == fullyQualifiedEventName + select e; var eventDescriptors = eventDescriptorQuery.ToArray(); if (!eventDescriptors.Any()) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index 9bec00edd..de6164fa9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -29,16 +29,15 @@ namespace Orchard.AuditTrail.Services { public void Sweep() { if (Monitor.TryEnter(_sweepLock)) { + Logger.Debug("Beginning sweep."); try { - Logger.Debug("Beginning sweep."); - // We don't need to check the audit trail for events to remove every minute. Let's stick with twice a day. - if (!TimeToTrim()) + if (!GetIsTimeToTrim()) return; - Logger.Debug("Starting audit trail trimming operation."); + Logger.Debug("Starting audit trail trimming."); var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.RetentionPeriod)); - Logger.Debug("Audit trail trimming operation completed. {0} records were deleted.", deletedRecords.Count()); + Logger.Debug("Audit trail trimming completed. {0} records were deleted.", deletedRecords.Count()); Settings.LastRunUtc = _clock.UtcNow; } catch (Exception ex) { @@ -51,7 +50,7 @@ namespace Orchard.AuditTrail.Services { } } - private bool TimeToTrim() { + private bool GetIsTimeToTrim() { var lastRun = Settings.LastRunUtc ?? DateTime.MinValue; var now = _clock.UtcNow; var interval = TimeSpan.FromHours(12); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs index cc082cdca..f578030d4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs @@ -16,7 +16,6 @@ namespace Orchard.AuditTrail.Services { } public override void Filter(QueryFilterContext context) { - // Common filters (username, from and to, category). var userName = context.Filters.Get("username"); var fromDate = context.Filters.Get("from.Date"); var fromTime = context.Filters.Get("from.Time"); @@ -27,16 +26,23 @@ namespace Orchard.AuditTrail.Services { var to = _dateServices.ConvertFromLocalString(toDate, toTime).Latest(); var query = context.Query; - if (!String.IsNullOrWhiteSpace(userName)) query = query.Where(x => x.UserName == userName); - if (!String.IsNullOrWhiteSpace(category)) query = query.Where(x => x.Category == category); - if (from != null) query = query.Where(x => x.CreatedUtc >= from); - if (to != null) query = query.Where(x => x.CreatedUtc <= to); + if (!String.IsNullOrWhiteSpace(userName)) { + query = query.Where(x => x.UserName == userName); + } + if (!String.IsNullOrWhiteSpace(category)) { + query = query.Where(x => x.Category == category); + } + if (from != null) { + query = query.Where(x => x.CreatedUtc >= from); + } + if (to != null) { + query = query.Where(x => x.CreatedUtc <= to); + } context.Query = query; } public override void DisplayFilter(DisplayFilterContext context) { - // Common filters (username, from and to, category). var userName = context.Filters.Get("username"); var fromDate = context.Filters.Get("from.Date"); var toDate = context.Filters.Get("to.Date"); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index 94ca56f4a..a361dd689 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -8,7 +8,7 @@ using Orchard.Security; namespace Orchard.AuditTrail.Services { public interface IAuditTrailManager : IDependency { /// - /// Returns a page of event records. + /// Gets a page of event records from the audit trail. /// /// The page number to get records from. /// The number of records to get. @@ -18,10 +18,10 @@ namespace Orchard.AuditTrail.Services { IPageOfItems GetRecords(int page, int pageSize, Filters filters = null, AuditTrailOrderBy orderBy = AuditTrailOrderBy.DateDescending); /// - /// Returns a single event record by ID. + /// Gets a single event record from the audit trail by ID. /// /// The event record ID. - /// A single event record by ID. + /// A single event record. AuditTrailEventRecord GetRecord(int id); /// diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs index e5e83a3fb..66d8ad697 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/AuditTrailEventDescriptor.cs @@ -7,10 +7,6 @@ namespace Orchard.AuditTrail.Services.Models { public LocalizedString Name { get; set; } public LocalizedString Description { get; set; } public bool IsEnabledByDefault { get; set; } - - /// - /// Wether the event can be disabled or not. - /// public bool IsMandatory { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs index fed7d2aa4..96750bf2b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DescribeFor.cs @@ -38,6 +38,7 @@ namespace Orchard.AuditTrail.Services.Models { IsEnabledByDefault = enableByDefault, IsMandatory = isMandatory }); + return this; } } From 50ee3fcd9d1405f2eb86afde4ffce12c1b612e6a Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 18:47:46 +0200 Subject: [PATCH 058/116] Added display of last trimming run to settings UI. --- .../AuditTrailTrimmingSettingsPartDriver.cs | 1 + .../Modules/Orchard.AuditTrail/Placement.info | 4 ++-- .../AuditTrailTrimmingSettingsViewModel.cs | 3 +++ .../Parts.AuditTrailTrimmingSettings.cshtml | 15 +++++++++++---- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 59c29a4a3..2975bfab9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -25,6 +25,7 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { var viewModel = new AuditTrailTrimmingSettingsViewModel { RetentionPeriod = part.RetentionPeriod, + LastRunUtc = part.LastRunUtc }; if (updater != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info index ae18bc77f..72e74a5cc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Placement.info @@ -2,8 +2,8 @@ + Parts_AuditTrailSettings_Edit="Content:0" + Parts_AuditTrailTrimmingSettings_Edit="Content:1"/> diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs index 8b4a9868d..bbdfa8842 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -1,5 +1,8 @@ +using System; + namespace Orchard.AuditTrail.ViewModels { public class AuditTrailTrimmingSettingsViewModel { public int RetentionPeriod { get; set; } + public DateTime? LastRunUtc { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index 61b11ae6b..2c3dd5c17 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -1,7 +1,14 @@ @model Orchard.AuditTrail.ViewModels.AuditTrailTrimmingSettingsViewModel

@T("Trimming settings")

- @Html.LabelFor(m => m.RetentionPeriod, T("Retention period")) - @Html.TextBoxFor(m => m.RetentionPeriod, new { @class = "text small" }) - @T("The number of days of audit log data to retain.") -
\ No newline at end of file +
+ @Html.LabelFor(m => m.RetentionPeriod, T("Retention period")) + @Html.TextBoxFor(m => m.RetentionPeriod, new { @class = "text small" }) + @T("The number of days of audit log data to retain.") +
+
+ @Html.LabelFor(m => m.LastRunUtc, T("Last run")) + @Html.TextBoxFor(m => m.LastRunUtc, new { @class = "text", disabled = "disabled" }) + @T("Indicates the last time the audit trail trimming process was run. The trimming process runs every 12 hours.") +
+
From 1fa28be0678b85e687fadcf37dad36d89bcd231d Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 19:03:07 +0200 Subject: [PATCH 059/116] Added task lease to audit trail trimming background task. --- .../Modules/Orchard.AuditTrail/Module.txt | 2 +- .../Orchard.AuditTrail.csproj | 4 +++ .../AuditTrailTrimmingBackgroundTask.cs | 31 +++++++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 58de6621b..21b38c987 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -20,7 +20,7 @@ Features: Name: Audit Trail Trimming Description: Provides a background task that regularly deletes old audit trail records. Category: Security - Dependencies: Orchard.AuditTrail + Dependencies: Orchard.AuditTrail, Orchard.TaskLease Orchard.AuditTrail.Users: Name: Audit Trail User Events Description: Provides audit trail support for user related events. diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 3ec3e3a6b..998a35d5b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -165,6 +165,10 @@ {d10ad48f-407d-4db5-a328-173ec7cb010f} Orchard.Roles + + {3f72a4e9-7b72-4260-b010-c16ec54f9baf} + Orchard.TaskLease + {79aed36e-abd0-4747-93d3-8722b042454b} Orchard.Users diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index de6164fa9..cf719cdfa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -7,6 +7,7 @@ using Orchard.Environment.Extensions; using Orchard.Logging; using Orchard.Services; using Orchard.Settings; +using Orchard.TaskLease.Services; using Orchard.Tasks; namespace Orchard.AuditTrail.Services { @@ -15,11 +16,18 @@ namespace Orchard.AuditTrail.Services { private static readonly object _sweepLock = new object(); private readonly ISiteService _siteService; private readonly IClock _clock; + private readonly ITaskLeaseService _taskLeaseService; private readonly IAuditTrailManager _auditTrailManager; - public AuditTrailTrimmingBackgroundTask(ISiteService siteService, IClock clock, IAuditTrailManager auditTrailManager) { + public AuditTrailTrimmingBackgroundTask( + ISiteService siteService, + IClock clock, + ITaskLeaseService taskLeaseService, + IAuditTrailManager auditTrailManager) { + _siteService = siteService; _clock = clock; + _taskLeaseService = taskLeaseService; _auditTrailManager = auditTrailManager; } @@ -29,16 +37,21 @@ namespace Orchard.AuditTrail.Services { public void Sweep() { if (Monitor.TryEnter(_sweepLock)) { - Logger.Debug("Beginning sweep."); try { - // We don't need to check the audit trail for events to remove every minute. Let's stick with twice a day. - if (!GetIsTimeToTrim()) - return; + Logger.Debug("Beginning sweep."); - Logger.Debug("Starting audit trail trimming."); - var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.RetentionPeriod)); - Logger.Debug("Audit trail trimming completed. {0} records were deleted.", deletedRecords.Count()); - Settings.LastRunUtc = _clock.UtcNow; + // Only allow this task to run on one farm node at a time. + if (_taskLeaseService.Acquire(GetType().FullName, _clock.UtcNow.AddHours(1)) != null) { + + // We don't need to check the audit trail for events to remove every minute. Let's stick with twice a day. + if (!GetIsTimeToTrim()) + return; + + Logger.Debug("Starting audit trail trimming."); + var deletedRecords = _auditTrailManager.Trim(TimeSpan.FromDays(Settings.RetentionPeriod)); + Logger.Debug("Audit trail trimming completed. {0} records were deleted.", deletedRecords.Count()); + Settings.LastRunUtc = _clock.UtcNow; + } } catch (Exception ex) { Logger.Error(ex, "Error during sweep."); From 4ea58a16158ca0f04195c132490c221dec6388ba Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 6 Jul 2014 19:35:51 +0200 Subject: [PATCH 060/116] Updated publishing profile. --- src/Orchard.Web/Orchard.Web.csproj | 2 +- .../Properties/PublishProfiles/audittrail-test.pubxml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index 1cb4b6c81..eb30459b9 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -221,7 +221,7 @@ - True + False False 30321 /OrchardLocal diff --git a/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml b/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml index 92b0744e9..d5e4f0d63 100644 --- a/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml +++ b/src/Orchard.Web/Properties/PublishProfiles/audittrail-test.pubxml @@ -14,7 +14,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt audittrail-test.scm.azurewebsites.net:443 audittrail-test - True + False WMSVC True $audittrail-test From 70cc73b2ed73622c86a85f3cf1aae71e70deadb9 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Mon, 7 Jul 2014 23:19:31 +0200 Subject: [PATCH 061/116] Removing some unneeded feature dependencies. --- src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt index 21b38c987..6abbce35d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Module.txt @@ -10,7 +10,6 @@ Features: Name: Audit Trail Description: Provides a log for recording and viewing back-end changes. Category: Security - Dependencies: Orchard.Users, Orchard.Roles, Orchard.ContentTypes Orchard.AuditTrail.ImportExport: Name: Audit Trail Import Export Description: Provides import/export functionality for the Audit Trail feature. From 7942801a5e0b7b57143618c8453ae87ad1309d2a Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Tue, 8 Jul 2014 02:51:34 +0200 Subject: [PATCH 062/116] Added localization of "last run" date in trimming settings. --- .../Drivers/AuditTrailTrimmingSettingsPartDriver.cs | 7 +++++-- .../ViewModels/AuditTrailTrimmingSettingsViewModel.cs | 2 +- .../Parts.AuditTrailTrimmingSettings.cshtml | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 2975bfab9..1742915a0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -3,15 +3,18 @@ using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.Environment.Extensions; +using Orchard.Localization.Services; using Orchard.Security; namespace Orchard.AuditTrail.Drivers { [OrchardFeature("Orchard.AuditTrail.Trimming")] public class AuditTrailTrimmingSettingsPartDriver : ContentPartDriver { private readonly IAuthorizer _authorizer; + private readonly IDateServices _dateServices; - public AuditTrailTrimmingSettingsPartDriver(IAuthorizer authorizer) { + public AuditTrailTrimmingSettingsPartDriver(IAuthorizer authorizer, IDateServices dateServices) { _authorizer = authorizer; + _dateServices = dateServices; } protected override DriverResult Editor(AuditTrailTrimmingSettingsPart part, dynamic shapeHelper) { @@ -25,7 +28,7 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { var viewModel = new AuditTrailTrimmingSettingsViewModel { RetentionPeriod = part.RetentionPeriod, - LastRunUtc = part.LastRunUtc + LastRun = _dateServices.ConvertToLocal(part.LastRunUtc) }; if (updater != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs index bbdfa8842..c0a426ea5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -3,6 +3,6 @@ using System; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailTrimmingSettingsViewModel { public int RetentionPeriod { get; set; } - public DateTime? LastRunUtc { get; set; } + public DateTime? LastRun { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index 2c3dd5c17..1330a4853 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -7,8 +7,8 @@ @T("The number of days of audit log data to retain.")
- @Html.LabelFor(m => m.LastRunUtc, T("Last run")) - @Html.TextBoxFor(m => m.LastRunUtc, new { @class = "text", disabled = "disabled" }) + @Html.LabelFor(m => m.LastRun, T("Last run")) + @Html.TextBoxFor(m => m.LastRun, new { @class = "text", disabled = "disabled" }) @T("Indicates the last time the audit trail trimming process was run. The trimming process runs every 12 hours.")
From fa40768fdad870671f6bc13bdb9967c380ba48b2 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Wed, 9 Jul 2014 00:38:45 +0200 Subject: [PATCH 063/116] Fixed localization of last trimming run date display. Added range validation to trimming settings. Added configurable setting for minimum trimming run interval. --- .../Drivers/AuditTrailTrimmingSettingsPartDriver.cs | 11 +++++++++-- .../Models/AuditTrailTrimmingSettingsPart.cs | 8 ++++++++ .../Services/AuditTrailTrimmingBackgroundTask.cs | 4 ++-- .../ViewModels/AuditTrailTrimmingSettingsViewModel.cs | 6 ++++-- .../Parts.AuditTrailTrimmingSettings.cshtml | 11 ++++++++--- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 1742915a0..8cd40d36c 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -3,6 +3,7 @@ using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.Environment.Extensions; +using Orchard.Localization; using Orchard.Localization.Services; using Orchard.Security; @@ -11,12 +12,17 @@ namespace Orchard.AuditTrail.Drivers { public class AuditTrailTrimmingSettingsPartDriver : ContentPartDriver { private readonly IAuthorizer _authorizer; private readonly IDateServices _dateServices; + private readonly IDateTimeFormatProvider _dateTimeLocalization; - public AuditTrailTrimmingSettingsPartDriver(IAuthorizer authorizer, IDateServices dateServices) { + public AuditTrailTrimmingSettingsPartDriver(IAuthorizer authorizer, IDateServices dateServices, IDateTimeFormatProvider dateTimeLocalization) { _authorizer = authorizer; _dateServices = dateServices; + _dateTimeLocalization = dateTimeLocalization; + T = NullLocalizer.Instance; } + public Localizer T { get; set; } + protected override DriverResult Editor(AuditTrailTrimmingSettingsPart part, dynamic shapeHelper) { return Editor(part, null, shapeHelper); } @@ -28,7 +34,8 @@ namespace Orchard.AuditTrail.Drivers { return ContentShape("Parts_AuditTrailTrimmingSettings_Edit", () => { var viewModel = new AuditTrailTrimmingSettingsViewModel { RetentionPeriod = part.RetentionPeriod, - LastRun = _dateServices.ConvertToLocal(part.LastRunUtc) + MinimumRunInterval = part.MinimumRunInterval, + LastRunDateString = _dateServices.ConvertToLocalString(part.LastRunUtc, _dateTimeLocalization.ShortDateTimeFormat, T("Never").Text) }; if (updater != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs index 8bec9677c..e0ad80d5a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailTrimmingSettingsPart.cs @@ -11,6 +11,14 @@ namespace Orchard.AuditTrail.Models { set { this.Store(x => x.RetentionPeriod, value); } } + /// + /// Gets or sets the miminum wait time in hours between audit trail trimming runs. + /// + public int MinimumRunInterval { + get { return this.Retrieve(x => x.MinimumRunInterval, defaultValue: 12); } + set { this.Store(x => x.MinimumRunInterval, value); } + } + /// /// Gets or sets the time in UTC at which the audit trail was last trimmed. /// diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index cf719cdfa..83da1ae69 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -66,8 +66,8 @@ namespace Orchard.AuditTrail.Services { private bool GetIsTimeToTrim() { var lastRun = Settings.LastRunUtc ?? DateTime.MinValue; var now = _clock.UtcNow; - var interval = TimeSpan.FromHours(12); - return now - lastRun > interval; + var interval = TimeSpan.FromHours(Settings.MinimumRunInterval); + return now - lastRun >= interval; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs index c0a426ea5..ec47152c5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailTrimmingSettingsViewModel.cs @@ -1,8 +1,10 @@ using System; +using System.ComponentModel.DataAnnotations; namespace Orchard.AuditTrail.ViewModels { public class AuditTrailTrimmingSettingsViewModel { - public int RetentionPeriod { get; set; } - public DateTime? LastRun { get; set; } + [Range(0, Int32.MaxValue)] public int RetentionPeriod { get; set; } + [Range(0, Int32.MaxValue)] public int MinimumRunInterval { get; set; } + public string LastRunDateString { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml index 1330a4853..ffd6f984a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailTrimmingSettings.cshtml @@ -7,8 +7,13 @@ @T("The number of days of audit log data to retain.")
- @Html.LabelFor(m => m.LastRun, T("Last run")) - @Html.TextBoxFor(m => m.LastRun, new { @class = "text", disabled = "disabled" }) - @T("Indicates the last time the audit trail trimming process was run. The trimming process runs every 12 hours.") + @Html.LabelFor(m => m.MinimumRunInterval, T("Minimum run interval")) + @Html.TextBoxFor(m => m.MinimumRunInterval, new { @class = "text small" }) + @T("The minimum number of hours to wait between trimming process runs. Enter 0 for continuous trimming.") +
+
+ @Html.LabelFor(m => m.LastRunDateString, T("Last run")) + @Html.TextBoxFor(m => m.LastRunDateString, new { @class = "text", disabled = "disabled" }) + @T("Indicates the last time the audit trail trimming process was run.")
From 279f89f7481d30c0491cc845c74f16f9c67f4655 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Wed, 9 Jul 2014 03:15:38 +0200 Subject: [PATCH 064/116] Fixed exception in model binding, causing event settings to never be persisted. --- .../Drivers/AuditTrailSettingsPartDriver.cs | 4 ++-- .../ViewModels/AuditTrailCategorySettingsViewModel.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index 97e21bc3e..80d75f3a7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -42,11 +42,11 @@ namespace Orchard.AuditTrail.Drivers { select new AuditTrailCategorySettingsViewModel { Category = categoryDescriptor.Category, Name = categoryDescriptor.Name, - Events = eventsQuery.ToArray() + Events = eventsQuery.ToList() }; var viewModel = new AuditTrailSettingsViewModel { - Categories = categoriesQuery.ToArray() + Categories = categoriesQuery.ToList() }; if (updater != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs index 81267c677..04d619a08 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCategorySettingsViewModel.cs @@ -5,6 +5,6 @@ namespace Orchard.AuditTrail.ViewModels { public class AuditTrailCategorySettingsViewModel { public string Category { get; set; } public LocalizedString Name { get; set; } - public IEnumerable Events { get; set; } + public IList Events { get; set; } } } \ No newline at end of file From be3fe746accdc947176421bd42a783094462e54d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 12:42:08 -0700 Subject: [PATCH 065/116] #165: Added short event name for sorting purposes. --- .../Orchard.AuditTrail/Controllers/AdminController.cs | 4 ++-- .../Drivers/AuditTrailPartDriver.cs | 4 +--- .../ImportExport/AuditTrailExportHandler.cs | 3 ++- .../ImportExport/AuditTrailImportHandler.cs | 3 ++- .../Modules/Orchard.AuditTrail/Migrations.cs | 3 ++- .../Models/AuditTrailEventRecord.cs | 3 ++- .../Services/AuditTrailEventDisplayBuilder.cs | 11 +++-------- .../Orchard.AuditTrail/Services/AuditTrailManager.cs | 5 +++-- 8 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index e192d0fb7..56bdd99c8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -42,7 +42,7 @@ namespace Orchard.AuditTrail.Controllers { var eventDescriptors = eventDescriptorsQuery.ToDictionary(x => x.Event); var recordViewModelsQuery = from record in pageOfData - let descriptor = eventDescriptors.ContainsKey(record.Event) ? eventDescriptors[record.Event] : default(AuditTrailEventDescriptor) + let descriptor = eventDescriptors.ContainsKey(record.FullEventName) ? eventDescriptors[record.FullEventName] : default(AuditTrailEventDescriptor) where descriptor != null select new AuditTrailEventSummaryViewModel { Record = record, @@ -66,7 +66,7 @@ namespace Orchard.AuditTrail.Controllers { return new HttpUnauthorizedResult(); var record = _auditTrailManager.GetRecord(id); - var descriptor = _auditTrailManager.DescribeEvent(record.Event); + var descriptor = _auditTrailManager.DescribeEvent(record.FullEventName); var detailsShape = _displayBuilder.BuildDisplay(record, "Detail"); var viewModel = new AuditTrailDetailsViewModel { Record = record, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 128ea8726..6e41a37f2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -1,10 +1,8 @@ using System.Collections.Generic; -using System.Globalization; using System.Linq; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Providers.Content; using Orchard.AuditTrail.Services; -using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.Settings; using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; @@ -53,7 +51,7 @@ namespace Orchard.AuditTrail.Drivers { from e in c.Events select e; var recordViewModels = from record in pageOfData - let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.Event) + let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.FullEventName) where descriptor != null select new AuditTrailEventSummaryViewModel { Record = record, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs index 82b5cace9..cf9483dde 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailExportHandler.cs @@ -35,7 +35,8 @@ namespace Orchard.AuditTrail.ImportExport { foreach (var record in records) { root.Add(new XElement("Event", - CreateAttribute("Name", record.Event), + CreateAttribute("Name", record.EventName), + CreateAttribute("FullName", record.FullEventName), CreateAttribute("Category", record.Category), CreateAttribute("User", record.UserName), CreateAttribute("CreatedUtc", record.CreatedUtc), diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs index 9ad6af060..7266138d9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs @@ -22,7 +22,8 @@ namespace Orchard.AuditTrail.ImportExport { foreach (var eventElement in recipeContext.RecipeStep.Step.Elements()) { var record = new AuditTrailEventRecord { - Event = eventElement.Attr("Name"), + EventName = eventElement.Attr("Name"), + FullEventName = eventElement.Attr("FullName"), Category = eventElement.Attr("Category"), UserName = eventElement.Attr("User"), CreatedUtc = eventElement.Attr("CreatedUtc"), diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs index f399c1756..30b109b82 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Migrations.cs @@ -10,7 +10,8 @@ namespace Orchard.AuditTrail { .Column("Id", c => c.PrimaryKey().Identity()) .Column("CreatedUtc") .Column("UserName", c => c.WithLength(64)) - .Column("Event", c => c.WithLength(256)) + .Column("EventName", c => c.WithLength(128)) + .Column("FullEventName", c => c.WithLength(512)) .Column("Category", c => c.WithLength(64)) .Column("ContentItemVersion_Id") .Column("EventData", c => c.Unlimited()) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs index f40fded26..af93c7fbb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs @@ -5,7 +5,8 @@ namespace Orchard.AuditTrail.Models { public virtual int Id { get; set; } public virtual DateTime CreatedUtc { get; set; } public virtual string UserName { get; set; } - public virtual string Event { get; set; } + public virtual string EventName { get; set; } + public virtual string FullEventName { get; set; } public virtual string Category { get; set; } public virtual string EventData { get; set; } public virtual string EventFilterKey { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs index 8dcb8ca8a..1f71abe3b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailEventDisplayBuilder.cs @@ -18,21 +18,16 @@ namespace Orchard.AuditTrail.Services { public dynamic BuildDisplay(AuditTrailEventRecord record, string displayType) { var eventData = _serializer.Deserialize(record.EventData); - var descriptor = _auditTrailManager.DescribeEvent(record.Event); + var descriptor = _auditTrailManager.DescribeEvent(record.FullEventName); var auditTrailEventShape = New.AuditTrailEvent(Record: record, EventData: eventData, Descriptor: descriptor); var metaData = (ShapeMetadata)auditTrailEventShape.Metadata; metaData.DisplayType = displayType; metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}", displayType)); metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}", record.Category)); metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}", displayType, record.Category)); - metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}__{1}", record.Category, GetShortEventName(record.Event))); - metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, GetShortEventName(record.Event))); + metaData.Alternates.Add(String.Format("AuditTrailEvent__{0}__{1}", record.Category, record.EventName)); + metaData.Alternates.Add(String.Format("AuditTrailEvent_{0}__{1}__{2}", displayType, record.Category, record.EventName)); return auditTrailEventShape; } - - private string GetShortEventName(string fullyQualifiedEventName) { - var index = fullyQualifiedEventName.LastIndexOf('.') + 1; - return fullyQualifiedEventName.Substring(index); - } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 249460a5b..d82ea6392 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -73,7 +73,7 @@ namespace Orchard.AuditTrail.Services { switch (orderBy) { case AuditTrailOrderBy.EventAscending: - query = query.OrderBy(x => x.Event).ThenByDescending(x => x.Id); + query = query.OrderBy(x => x.EventName).ThenByDescending(x => x.Id); break; case AuditTrailOrderBy.CategoryAscending: query = query.OrderBy(x => x.Category).ThenByDescending(x => x.Id); @@ -139,7 +139,8 @@ namespace Orchard.AuditTrail.Services { var record = new AuditTrailEventRecord { Category = eventDescriptor.CategoryDescriptor.Category, - Event = eventDescriptor.Event, + EventName = eventName, + FullEventName = eventDescriptor.Event, CreatedUtc = _clock.UtcNow, UserName = user != null ? user.UserName : null, EventData = _serializer.Serialize(context.EventData), From c12f4364fdceef38ad680be3c2f2d3d7c36fe730 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 13:22:29 -0700 Subject: [PATCH 066/116] Removing unnecessary summary admin views. --- .../Orchard.AuditTrail.csproj | 20 ------------------- ...nt-ContentPart-Created.SummaryAdmin.cshtml | 9 --------- ...ContentPart-FieldAdded.SummaryAdmin.cshtml | 12 ----------- ...ntentPart-FieldRemoved.SummaryAdmin.cshtml | 10 ---------- ...t-FieldSettingsUpdated.SummaryAdmin.cshtml | 10 ---------- ...rt-PartSettingsUpdated.SummaryAdmin.cshtml | 9 --------- ...nt-ContentPart-Removed.SummaryAdmin.cshtml | 9 --------- ...nt-ContentType-Created.SummaryAdmin.cshtml | 10 ---------- ...-ContentType-PartAdded.SummaryAdmin.cshtml | 10 ---------- ...ontentType-PartRemoved.SummaryAdmin.cshtml | 10 ---------- ...pe-PartSettingsUpdated.SummaryAdmin.cshtml | 10 ---------- ...nt-ContentType-Removed.SummaryAdmin.cshtml | 10 ---------- ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 9 --------- ...t-Role-PermissionAdded.SummaryAdmin.cshtml | 10 ---------- ...Role-PermissionRemoved.SummaryAdmin.cshtml | 10 ---------- ...Event-Role-RoleCreated.SummaryAdmin.cshtml | 9 --------- ...Event-Role-RoleRenamed.SummaryAdmin.cshtml | 10 ---------- .../AuditTrailEvent-User.SummaryAdmin.cshtml | 9 --------- .../Views/AuditTrailEvent.SummaryAdmin.cshtml | 3 --- .../Views/AuditTrailEvent.cshtml | 4 +--- 20 files changed, 1 insertion(+), 192 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 998a35d5b..fa1169001 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -95,23 +95,7 @@ - - - - - - - - - - - - - - - - @@ -122,7 +106,6 @@ - @@ -264,9 +247,6 @@ - - - diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml deleted file mode 100644 index dedd7c64d..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Created the {0} content part.", contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml deleted file mode 100644 index c9bb76bed..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.SummaryAdmin.cshtml +++ /dev/null @@ -1,12 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); - var contentFieldName = eventData.Get("ContentFieldName"); - var contentFieldTypeName = eventData.Get("ContentFieldTypeName"); - var contentDisplayName = eventData.Get("ContentDisplayName"); -} - -
- @T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml deleted file mode 100644 index eed00a730..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); - var contentFieldName = eventData.Get("ContentFieldName"); -} - -
- @T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml deleted file mode 100644 index 5edd0a3fb..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); - var contentFieldName = eventData.Get("ContentFieldName"); -} - -
- @T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml deleted file mode 100644 index d22fcf49a..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Settings for the {0} content part were updated.", contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml deleted file mode 100644 index 167daf607..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Removed the {0} content part.", contentPartName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml deleted file mode 100644 index 80d4a2ca0..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); - var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); -} - -
- @T("Created the {0} content type.", contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml deleted file mode 100644 index 8bace8ba5..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml deleted file mode 100644 index 3a0697226..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml deleted file mode 100644 index c9f146706..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); - var contentPartName = eventData.Get("ContentPartName"); -} - -
- @T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml deleted file mode 100644 index bdbbc7083..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); - var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); -} - -
- @T("Removed the {0} content type.", contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml deleted file mode 100644 index 080f1f6e4..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var contentTypeName = eventData.Get("ContentTypeName"); -} - -
- @T("Settings for the {0} content type were updated.", contentTypeName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml deleted file mode 100644 index 6d9b76ecc..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var roleName = eventData.Get("RoleName"); - var permissionName = eventData.Get("PermissionName"); -} - -
- @T("Added the {0} permission to the {1} role.", permissionName, roleName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml deleted file mode 100644 index ffbc0bc40..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var roleName = eventData.Get("RoleName"); - var permissionName = eventData.Get("PermissionName"); -} - -
- @T("Removed the {0} permission from the {1} role.", permissionName, roleName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml deleted file mode 100644 index 29e31861f..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var roleName = eventData.Get("RoleName"); -} - -
- @T("Created {0} role.", roleName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml deleted file mode 100644 index 769eabd6f..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.SummaryAdmin.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var previousRoleName = eventData.Get("PreviousRoleName"); - var newRoleName = eventData.Get("NewRoleName"); -} - -
- @T("Renamed {0} to {1}.", previousRoleName, newRoleName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml deleted file mode 100644 index 87e06a634..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.SummaryAdmin.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@using Orchard.AuditTrail.Helpers -@{ - var eventData = (IDictionary) Model.EventData; - var userName = eventData.Get("UserName"); -} - -
- @T("User: {0}", userName) -
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml deleted file mode 100644 index ff029a741..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.SummaryAdmin.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - var model = Model; -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml index ff029a741..851b0afd2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent.cshtml @@ -1,3 +1 @@ -@{ - var model = Model; -} \ No newline at end of file +@*No additional data to show*@ \ No newline at end of file From 3216e6629e77ed8f3da0fc5c0797e5e5ee886c37 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 13:46:32 -0700 Subject: [PATCH 067/116] Fixing nested form issue. --- .../Orchard.AuditTrail/Views/Admin/Index.cshtml | 2 +- .../Orchard.AuditTrail/Views/AuditTrailFilter.cshtml | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index 6ca727378..d1f934fc5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -22,7 +22,7 @@
- + }
@if (!Model.Records.Any()) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml index 04a81505b..7dfa33830 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter.cshtml @@ -1,7 +1,5 @@ -@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) { - foreach (var item in Model) { -
- @Display(item) -
- } -} +@foreach (var item in Model) { +
+ @Display(item) +
+} \ No newline at end of file From d268eb6fbf2ee29086123cd495be62b3f6ee7023 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 13:47:05 -0700 Subject: [PATCH 068/116] #169: Fixing filter date picker issue. --- .../Views/AuditTrailFilter-Common-Date-From.cshtml | 4 ++-- .../Views/AuditTrailFilter-Common-Date-To.cshtml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml index a97c78674..1877a1777 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-From.cshtml @@ -1,6 +1,6 @@ @using Orchard.Core.Common.ViewModels @{ - var editor = (DateTimeEditor)Model.Editor; + var from = (DateTimeEditor)Model.Editor; } @Html.Label("from.Date", T("From:").Text) -@Html.EditorFor(m => editor) +@Html.EditorFor(m => from) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml index d61f4593d..1c1ebd99e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailFilter-Common-Date-To.cshtml @@ -1,6 +1,6 @@ @using Orchard.Core.Common.ViewModels @{ - var editor = (DateTimeEditor)Model.Editor; + var to = (DateTimeEditor)Model.Editor; } @Html.Label("to.Date", T("To:").Text) -@Html.EditorFor(m => editor) +@Html.EditorFor(m => to) From 14e8ff5e9b86d155ab248298f7b7b84238a674a4 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 13:59:27 -0700 Subject: [PATCH 069/116] #172: Retaining page size upon changing filter parameters. --- .../Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index d1f934fc5..eafa3016d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -23,6 +23,7 @@
+ }
@if (!Model.Records.Any()) { From 232a351babffcf789f34ee8fafa2e2d03fbb9952 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 14:05:15 -0700 Subject: [PATCH 070/116] #177: Fixing issue when requesting all records. --- .../Orchard.AuditTrail/Services/AuditTrailManager.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index d82ea6392..4ac2fd441 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -85,9 +85,13 @@ namespace Orchard.AuditTrail.Services { var totalItemCount = query.Count(); var startIndex = (page - 1) * pageSize; - var records = query.Skip(startIndex).Take(pageSize); - return new PageOfItems(records) { + query = query.Skip(startIndex); + + if (pageSize > 0) + query = query.Take(pageSize); + + return new PageOfItems(query) { PageNumber = page, PageSize = pageSize, TotalItemCount = totalItemCount From ac12bf170339c7fcd58404670318ced4bfcdd4f3 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:23:27 -0700 Subject: [PATCH 071/116] Fixing a security hole. --- .../Drivers/AuditTrailSettingsPartDriver.cs | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs index 80d75f3a7..6f235f843 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailSettingsPartDriver.cs @@ -1,6 +1,8 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; @@ -31,12 +33,12 @@ namespace Orchard.AuditTrail.Drivers { from categoryDescriptor in descriptors let eventsQuery = from eventDescriptor in categoryDescriptor.Events - let eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventDescriptor.Event) + let eventSetting = GetOrCreate(eventSettings, eventDescriptor) select new AuditTrailEventSettingsViewModel { Event = eventDescriptor.Event, Name = eventDescriptor.Name, Description = eventDescriptor.Description, - IsEnabled = eventDescriptor.IsMandatory || (eventSetting != null ? eventSetting.IsEnabled : eventDescriptor.IsEnabledByDefault), + IsEnabled = eventDescriptor.IsMandatory || eventSetting.IsEnabled, IsMandatory = eventDescriptor.IsMandatory } select new AuditTrailCategorySettingsViewModel { @@ -49,18 +51,17 @@ namespace Orchard.AuditTrail.Drivers { Categories = categoriesQuery.ToList() }; + // Update the settings as we may have added new settings. + part.EventSettings = eventSettings; + if (updater != null) { + var eventsDictionary = _auditTrailManager.DescribeProviders().Describe().SelectMany(x => x.Events).ToDictionary(x => x.Event); if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { foreach (var eventSettingViewModel in viewModel.Categories.SelectMany(x => x.Events)) { var eventSetting = eventSettings.FirstOrDefault(x => x.EventName == eventSettingViewModel.Event); + var descriptor = eventsDictionary[eventSetting.EventName]; - if (eventSetting == null) { - eventSetting = new AuditTrailEventSetting { EventName = eventSettingViewModel.Event}; - eventSettings.Add(eventSetting); - } - - // TODO: Security hole! IsMandatory could be spoofed in the request! - eventSetting.IsEnabled = eventSettingViewModel.IsEnabled || eventSettingViewModel.IsMandatory; + eventSetting.IsEnabled = eventSettingViewModel.IsEnabled || descriptor.IsMandatory; } part.EventSettings = eventSettings; } @@ -69,5 +70,23 @@ namespace Orchard.AuditTrail.Drivers { return shapeHelper.EditorTemplate(TemplateName: "Parts.AuditTrailSettings", Model: viewModel, Prefix: Prefix); }).OnGroup("Audit Trail"); } + + /// + /// We're creating settings on the fly so that when the user updates the settings the first time, we won't log a massive amount of event settings that have changed. + /// + private AuditTrailEventSetting GetOrCreate(ICollection settings, AuditTrailEventDescriptor descriptor) { + var setting = settings.FirstOrDefault(x => x.EventName == descriptor.Event); + + if (setting == null) { + setting = new AuditTrailEventSetting { + EventName = descriptor.Event, + IsEnabled = descriptor.IsMandatory || descriptor.IsEnabledByDefault + }; + + settings.Add(setting); + } + + return setting; + } } } \ No newline at end of file From 921ec3d5120739a41eaa63aa8dc71251c5b419b5 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:25:42 -0700 Subject: [PATCH 072/116] #182: Storing updated audit trail settings with the event record and adding audit trail event settings changed event shape views. --- .../Handlers/AuditTrailSettingsPartHandler.cs | 38 +++------------ .../Helpers/EventNameExtensions.cs | 7 ++- .../Models/AuditTrailEventRecord.cs | 5 ++ .../Orchard.AuditTrail.csproj | 7 ++- .../Services/AuditTrailManager.cs | 31 ++++++++++++ .../Services/IAuditTrailManager.cs | 9 ++++ ...ailShapes.cs => AuditTrailFilterShapes.cs} | 2 +- .../Shapes/AuditTrailSettingsEventShape.cs | 48 +++++++++++++++++++ .../Styles/audittrail-settings-event.css | 10 ++++ ...ditTrailEventDescriptorSettingViewModel.cs | 9 ++++ .../AuditTrailEventSettingsViewModel.cs | 1 - ...Settings-EventsChanged.SummaryAdmin.cshtml | 9 ++++ ...nt-AuditTrailSettings-EventsChanged.cshtml | 34 +++++++++++++ .../Parts.AuditTrailSettings.cshtml | 1 - 14 files changed, 174 insertions(+), 37 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/{AuditTrailShapes.cs => AuditTrailFilterShapes.cs} (89%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventDescriptorSettingViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs index 33306c224..0f95c1c0d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs @@ -37,9 +37,9 @@ namespace Orchard.AuditTrail.Handlers { } private void SetupLazyFields(ActivatedContentContext context, AuditTrailSettingsPart part) { - part._eventProviderSettingsField.Loader(() => DeserializeProviderConfiguration(part.Retrieve("Events"))); + part._eventProviderSettingsField.Loader(() => _auditTrailManager.DeserializeProviderConfiguration(part.Retrieve("Events"))); part._eventProviderSettingsField.Setter(value => { - part.Store("Events", SerializeProviderConfiguration(value)); + part.Store("Events", _auditTrailManager.SerializeProviderConfiguration(value)); _signals.Trigger("AuditTrail.EventSettings"); return value; }); @@ -57,37 +57,11 @@ namespace Orchard.AuditTrail.Handlers { _auditTrailManager.CreateRecord( eventName: SettingsAuditTrailEventProvider.EventsChanged, + eventData: new Dictionary { + {"OldSettings", _oldEventSettings}, + {"NewSettings", newEventSettings} + }, user: _wca.GetContext().CurrentUser); } - - - private IEnumerable DeserializeProviderConfiguration(string data) { - if (String.IsNullOrWhiteSpace(data)) - return Enumerable.Empty(); - - try { - var doc = XDocument.Parse(data); - return doc.Element("Events").Elements("Event").Select(x => new AuditTrailEventSetting { - EventName = x.Attr("Name"), - IsEnabled = x.Attr("IsEnabled") - }).ToArray(); - - } - catch (Exception ex) { - Logger.Error(ex, "Error occurred during deserialization of audit trail settings."); - } - return Enumerable.Empty(); - } - - private string SerializeProviderConfiguration(IEnumerable settings) { - var doc = new XDocument( - new XElement("Events", - settings.Select(x => - new XElement("Event", - new XAttribute("Name", x.EventName), - new XAttribute("IsEnabled", x.IsEnabled))))); - - return doc.ToString(SaveOptions.DisableFormatting); - } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs index 5302a8fa3..2b8235182 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/EventNameExtensions.cs @@ -2,7 +2,7 @@ using Orchard.AuditTrail.Services; namespace Orchard.AuditTrail.Helpers { - internal static class EventNameExtensions { + public static class EventNameExtensions { public static string GetFullyQualifiedEventName(string eventName) where T : IAuditTrailEventProvider { return GetFullyQualifiedEventName(typeof(T), eventName); } @@ -10,5 +10,10 @@ namespace Orchard.AuditTrail.Helpers { public static string GetFullyQualifiedEventName(Type providerType, string eventName) { return String.Format("{0}.{1}", providerType.FullName, eventName); } + + public static string GetShortEventName(string fullyQualifiedEventName) { + var index = fullyQualifiedEventName.LastIndexOf('.') + 1; + return fullyQualifiedEventName.Substring(index); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs index af93c7fbb..77530e2de 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailEventRecord.cs @@ -1,4 +1,5 @@ using System; +using Orchard.Data.Conventions; namespace Orchard.AuditTrail.Models { public class AuditTrailEventRecord { @@ -8,9 +9,13 @@ namespace Orchard.AuditTrail.Models { public virtual string EventName { get; set; } public virtual string FullEventName { get; set; } public virtual string Category { get; set; } + + [StringLengthMax] public virtual string EventData { get; set; } public virtual string EventFilterKey { get; set; } public virtual string EventFilterData { get; set; } + + [StringLengthMax] public virtual string Comment { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index fa1169001..2ffe0e270 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -84,6 +84,7 @@ + @@ -126,6 +127,8 @@ + + @@ -187,8 +190,10 @@ - + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 4ac2fd441..82ad787b7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Xml.Linq; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services.Models; @@ -9,6 +10,7 @@ using Orchard.Collections; using Orchard.ContentManagement; using Orchard.Data; using Orchard.DisplayManagement; +using Orchard.Logging; using Orchard.Security; using Orchard.Services; using Orchard.Settings; @@ -215,5 +217,34 @@ namespace Orchard.AuditTrail.Services { return records; } + + public string SerializeProviderConfiguration(IEnumerable settings) { + var doc = new XDocument( + new XElement("Events", + settings.Select(x => + new XElement("Event", + new XAttribute("Name", x.EventName), + new XAttribute("IsEnabled", x.IsEnabled))))); + + return doc.ToString(SaveOptions.DisableFormatting); + } + + public IEnumerable DeserializeProviderConfiguration(string data) { + if (String.IsNullOrWhiteSpace(data)) + return Enumerable.Empty(); + + try { + var doc = XDocument.Parse(data); + return doc.Element("Events").Elements("Event").Select(x => new AuditTrailEventSetting { + EventName = x.Attr("Name"), + IsEnabled = x.Attr("IsEnabled") + }).ToArray(); + + } + catch (Exception ex) { + Logger.Error(ex, "Error occurred during deserialization of audit trail settings."); + } + return Enumerable.Empty(); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs index a361dd689..47fc2876f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/IAuditTrailManager.cs @@ -76,5 +76,14 @@ namespace Orchard.AuditTrail.Services { /// A list of deleted records. IEnumerable Trim(TimeSpan retentionPeriod); + /// + /// Serializes the specified list of settings into a string. + /// + string SerializeProviderConfiguration(IEnumerable settings); + + /// + /// Deserializes the specified string into a list of settings. + /// + IEnumerable DeserializeProviderConfiguration(string data); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs similarity index 89% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs index 2e4722f79..c7457083d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs @@ -2,7 +2,7 @@ using Orchard.DisplayManagement; namespace Orchard.AuditTrail.Shapes { - public class AuditTrailShapes : IDependency { + public class AuditTrailFilterShapes : IDependency { [Shape] public void AuditTrailFilterDisplay(dynamic Shape, dynamic Display, TextWriter Output) { DispayChildren(Shape, Display, Output); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs new file mode 100644 index 000000000..13514fea2 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs @@ -0,0 +1,48 @@ +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.Environment; + +namespace Orchard.AuditTrail.Shapes { + public class AuditTrailSettingsEventShape : IShapeTableProvider { + private readonly Work _auditTrailManager; + public AuditTrailSettingsEventShape(Work 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.EventsChanged)) + return; + + var eventData = (IDictionary)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; + }); + } + + private IEnumerable GetDiffQuery(IEnumerable oldSettings, IEnumerable newSettings) { + var oldDictionary = oldSettings.ToDictionary(x => x.EventName); + + return from newSetting in newSettings + let oldSetting = oldDictionary.ContainsKey(newSetting.EventName) ? oldDictionary[newSetting.EventName] : default(AuditTrailEventSetting) + where oldSetting == null || oldSetting.IsEnabled != newSetting.IsEnabled + select new AuditTrailEventDescriptorSettingViewModel { + Setting = newSetting, + Descriptor = _auditTrailManager.Value.DescribeEvent(newSetting.EventName) + }; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css new file mode 100644 index 000000000..8de6a3828 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css @@ -0,0 +1,10 @@ +section.audittrail-settings-event table.audittrail-events { + width: auto; + margin: 0; +} + +section.audittrail-settings-event tbody.audittrail-category tr th { + background-color: #ebebeb; + font-size: 1.1em; + font-weight: bold; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventDescriptorSettingViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventDescriptorSettingViewModel.cs new file mode 100644 index 000000000..d8652e987 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventDescriptorSettingViewModel.cs @@ -0,0 +1,9 @@ +using Orchard.AuditTrail.Models; +using Orchard.AuditTrail.Services.Models; + +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailEventDescriptorSettingViewModel { + public AuditTrailEventDescriptor Descriptor { get; set; } + public AuditTrailEventSetting Setting { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs index ff79dff28..615936319 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailEventSettingsViewModel.cs @@ -1,4 +1,3 @@ -using System.Collections; using Orchard.Localization; namespace Orchard.AuditTrail.ViewModels { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml new file mode 100644 index 000000000..3d1474c56 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.ViewModels +@{ + var diff = (IList)Model.Diff; + var descriptions = String.Join("
", diff.Select(x => T("{0} ({1}) was {2}", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text)); +} + +
+ @Html.Raw(descriptions) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml new file mode 100644 index 000000000..d12e7eeb7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml @@ -0,0 +1,34 @@ +@using Orchard.AuditTrail.ViewModels +@{ + Style.Include("audittrail-settings-event.css"); +} +@{ + var diff = (IList)Model.Diff; + var groups = diff.GroupBy(x => x.Descriptor.CategoryDescriptor.Name).OrderBy(x => x.Key.Text); +} + +
+
@T("Event") @T("Category")@T("Event") @T("User") @T("Timestamp")@T("Comment") @T("Summary")@T("Comment")
@record.EventDescriptor.Name @record.CategoryDescriptor.Name@record.EventDescriptor.Name @record.Record.UserName @Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@record.Record.Comment @Display(record.SummaryShape)@record.Record.Comment @Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
+ + + + + + + + @foreach (var group in groups) { + + + + + @foreach (var eventSetting in group.OrderBy(x => x.Descriptor.Name.Text)) { + + + + + + } + + } +
@T("Event")@T("Description")@T("New Status")
@group.Key
@eventSetting.Descriptor.Name@eventSetting.Descriptor.Description@T(eventSetting.Setting.IsEnabled ? "Enabled" : "Disabled")
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml index 144acecf5..bf2f61404 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrailSettings.cshtml @@ -2,7 +2,6 @@ @{ Style.Include("audittrail-settings.css"); Script.Require("ShapesBase"); - //Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); Script.Include("audittrail-checkall.js").AtFoot(); }
From 455fcc26e887bab4e7b7d1b2ca9fdd5df3f27671 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:32:51 -0700 Subject: [PATCH 073/116] Restoring renamed file. --- .../Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 2ffe0e270..53aff618d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -127,7 +127,7 @@ - + From 98153eb25c5e834bc10021037dd7dc16bd88e01c Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:33:22 -0700 Subject: [PATCH 074/116] #183: Updating minimum run interval upon save. --- .../Drivers/AuditTrailTrimmingSettingsPartDriver.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs index 8cd40d36c..f48d13cf2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailTrimmingSettingsPartDriver.cs @@ -41,6 +41,7 @@ namespace Orchard.AuditTrail.Drivers { if (updater != null) { if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { part.RetentionPeriod = viewModel.RetentionPeriod; + part.MinimumRunInterval = viewModel.MinimumRunInterval; } } From 5f61ebeee56a50addc06d6cd3fea93f977a48b16 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:46:59 -0700 Subject: [PATCH 075/116] Fixed trimming retention period interpretation. When the retention period was set to 0, the events would not be deleted until after 1 day. This has been fixed by taking the last hour of the current day and subtracting the retention period from that value, and then doing an "inclusive less than" check. --- .../Orchard.AuditTrail/Helpers/DateTimeExtensions.cs | 11 +++++++++-- .../Orchard.AuditTrail/Services/AuditTrailManager.cs | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs index 0289ca343..ad5eb75a9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/DateTimeExtensions.cs @@ -6,8 +6,11 @@ namespace Orchard.AuditTrail.Helpers { if (value == null) return null; - var v = value.Value; - return new DateTime(v.Year, v.Month, v.Day, 0, 0, 0, 0, v.Kind); + return Earliest(value.Value); + } + + public static DateTime Earliest(this DateTime value) { + return new DateTime(value.Year, value.Month, value.Day, 0, 0, 0, 0, value.Kind); } public static DateTime? Latest(this DateTime? value) { @@ -17,5 +20,9 @@ namespace Orchard.AuditTrail.Helpers { var v = value.Value; return new DateTime(v.Year, v.Month, v.Day, 23, 59, 59, 999, v.Kind); } + + public static DateTime Latest(this DateTime value) { + return new DateTime(value.Year, value.Month, value.Day, 23, 59, 59, 999, value.Kind); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index 82ad787b7..a9f9f0af0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -207,8 +207,8 @@ namespace Orchard.AuditTrail.Services { } public IEnumerable Trim(TimeSpan retentionPeriod) { - var dateThreshold = _clock.UtcNow.Date - retentionPeriod; - var query = _auditTrailRepository.Table.Where(x => x.CreatedUtc < dateThreshold); + var dateThreshold = (_clock.UtcNow.Latest() - retentionPeriod); + var query = _auditTrailRepository.Table.Where(x => x.CreatedUtc <= dateThreshold); var records = query.ToArray(); foreach (var record in records) { From 27455d46fdf346b64df5c7085d9aac4abefe98dc Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:51:14 -0700 Subject: [PATCH 076/116] #185: Improving event description. --- .../ContentDefinition/ContentTypeAuditTrailEventProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 6761a90ba..1bac9f6fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -29,7 +29,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { .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, 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 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); context.QueryFilter(QueryFilter); context.DisplayFilter(DisplayFilter); From 2e0ddb65be98eda7d2df9147316f6ce516c9ef3a Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 22:59:30 -0700 Subject: [PATCH 077/116] Fixing content definition event handler. --- .../ContentDefinitionEventHandler.cs | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs index cf9c96e86..69bb809a4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentDefinitionEventHandler.cs @@ -15,31 +15,31 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { _wca = wca; } - public void ContentTypeCreated(dynamic context) { + public void ContentTypeCreated(ContentTypeCreatedContext context) { RecordContentTypeAuditTrailEvent(ContentTypeAuditTrailEventProvider.Created, context.ContentTypeDefinition); } - public void ContentTypeRemoved(dynamic context) { + public void ContentTypeRemoved(ContentTypeRemovedContext context) { RecordContentTypeAuditTrailEvent(ContentTypeAuditTrailEventProvider.Removed, context.ContentTypeDefinition); } - public void ContentPartCreated(dynamic context) { + public void ContentPartCreated(ContentPartCreatedContext context) { RecordContentPartAuditTrailEvent(ContentPartAuditTrailEventProvider.Created, context.ContentPartDefinition); } - public void ContentPartRemoved(dynamic context) { + public void ContentPartRemoved(ContentPartRemovedContext context) { RecordContentPartAuditTrailEvent(ContentPartAuditTrailEventProvider.Removed, context.ContentPartDefinition); } - public void ContentPartAttached(dynamic context) { + public void ContentPartAttached(ContentPartAttachedContext context) { RecordContentTypePartAuditTrailEvent(ContentTypeAuditTrailEventProvider.PartAdded, context.ContentTypeName, context.ContentPartName); } - public void ContentPartDetached(dynamic context) { + public void ContentPartDetached(ContentPartDetachedContext context) { RecordContentTypePartAuditTrailEvent(ContentTypeAuditTrailEventProvider.PartRemoved, context.ContentTypeName, context.ContentPartName); } - public void ContentFieldAttached(dynamic context) { + public void ContentFieldAttached(ContentFieldAttachedContext context) { var eventData = new Dictionary { {"ContentPartName", context.ContentPartName}, {"ContentFieldName", context.ContentFieldName}, @@ -49,7 +49,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { _auditTrailManager.CreateRecord(ContentPartAuditTrailEventProvider.FieldAdded, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contentpart", eventFilterData: context.ContentPartName); } - public void ContentFieldDetached(dynamic context) { + public void ContentFieldDetached(ContentFieldDetachedContext context) { var eventData = new Dictionary { {"ContentPartName", context.ContentPartName}, {"ContentFieldName", context.ContentFieldName} @@ -79,14 +79,5 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { }; _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); } - - public void ContentTypeCreated(ContentTypeCreatedContext context) {} - public void ContentTypeRemoved(ContentTypeRemovedContext context) {} - public void ContentPartCreated(ContentPartCreatedContext context) {} - public void ContentPartRemoved(ContentPartRemovedContext context) {} - public void ContentPartAttached(ContentPartAttachedContext context) {} - public void ContentPartDetached(ContentPartDetachedContext context) {} - public void ContentFieldAttached(ContentFieldAttachedContext context) {} - public void ContentFieldDetached(ContentFieldDetachedContext context) {} } } \ No newline at end of file From be884466c9d53863a6a3bae0c9aed633f2ddfbf0 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 23:21:18 -0700 Subject: [PATCH 078/116] Recording minimum run interval setting. --- .../Handlers/AuditTrailTrimmingSettingsPartHandler.cs | 9 +++++++-- ...ent-AuditTrailSettings-TrimmingSettingsChanged.cshtml | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs index bd9636e3f..374cffe45 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs @@ -13,6 +13,7 @@ namespace Orchard.AuditTrail.Handlers { private int _oldRetentionPeriod; private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; + private int _oldMinimumRunInterval; public AuditTrailTrimmingSettingsPartHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca) { _auditTrailManager = auditTrailManager; @@ -32,12 +33,14 @@ namespace Orchard.AuditTrail.Handlers { private void BeginUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { _oldRetentionPeriod = part.RetentionPeriod; + _oldMinimumRunInterval = part.MinimumRunInterval; } private void EndUpdateEvent(UpdateContentContext context, AuditTrailTrimmingSettingsPart part) { var newRetentionPeriod = part.RetentionPeriod; + var newMinimumRunInterval = part.MinimumRunInterval; - if (newRetentionPeriod == _oldRetentionPeriod) + if (newRetentionPeriod == _oldRetentionPeriod && newMinimumRunInterval == _oldMinimumRunInterval) return; _auditTrailManager.CreateRecord( @@ -45,7 +48,9 @@ namespace Orchard.AuditTrail.Handlers { user: _wca.GetContext().CurrentUser, eventData: new Dictionary { {"OldRetentionPeriod", _oldRetentionPeriod}, - {"NewRetentionPeriod", newRetentionPeriod} + {"NewRetentionPeriod", newRetentionPeriod}, + {"OldMinimumRunInterval", _oldMinimumRunInterval}, + {"NewMinimumRunInterval", newMinimumRunInterval} }); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index f68bcfd2c..4a99c542f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -3,8 +3,11 @@ var eventData = (IDictionary)Model.EventData; var oldRetentionPeriod = eventData.Get("OldRetentionPeriod"); var newRetentionPeriod = eventData.Get("NewRetentionPeriod"); + var oldMinimumRunInterval = eventData.Get("OldMinimumRunInterval"); + var newMinimumRunInterval = eventData.Get("NewMinimumRunInterval"); }
- @T("Trimming retention period changed from {0} to {1}", oldRetentionPeriod, newRetentionPeriod) +
@T("Trimming retention period changed from {0} to {1}", oldRetentionPeriod, newRetentionPeriod)
+
@T("Minimum run interval changed from {0} to {1}", oldMinimumRunInterval, newMinimumRunInterval)
\ No newline at end of file From 5201422317d21171c20eeae76d0cf30c05bd91b2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 23:24:52 -0700 Subject: [PATCH 079/116] Improving audit trail settings event log display text. --- ...ailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index 4a99c542f..9ad57852b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -8,6 +8,6 @@ }
-
@T("Trimming retention period changed from {0} to {1}", oldRetentionPeriod, newRetentionPeriod)
-
@T("Minimum run interval changed from {0} to {1}", oldMinimumRunInterval, newMinimumRunInterval)
+
@T("Trimming retention period changed from {0} to {1}", T.Plural("1 day", "{0} days", oldRetentionPeriod), T.Plural("1 day", "{0} days", newRetentionPeriod))
+
@T("Minimum run interval changed from {0} to {1}", T.Plural("1 hour", "{0} hours", oldMinimumRunInterval), T.Plural("1 hour", "{0} hours", newMinimumRunInterval))
\ No newline at end of file From 655467d823d8edb839d98c44134164a4e449ac5b Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 12 Jul 2014 23:49:20 -0700 Subject: [PATCH 080/116] Adding and implementing ImportAuditTrail permission. --- .../ImportExport/AuditTrailImportHandler.cs | 14 +++++++++++++- .../Modules/Orchard.AuditTrail/Permissions.cs | 12 ++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs index 7266138d9..8c2bca005 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ImportExport/AuditTrailImportHandler.cs @@ -3,16 +3,22 @@ using Orchard.AuditTrail.Models; using Orchard.ContentManagement; using Orchard.Data; using Orchard.Environment.Extensions; +using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; +using Orchard.Security; namespace Orchard.AuditTrail.ImportExport { [OrchardFeature("Orchard.AuditTrail.ImportExport")] public class AuditTrailImportHandler : Component, IRecipeHandler { private readonly IRepository _auditTrailEventRepository; + private readonly IAuthorizer _authorizer; + private readonly IWorkContextAccessor _wca; - public AuditTrailImportHandler(IRepository auditTrailEventRepository) { + public AuditTrailImportHandler(IRepository auditTrailEventRepository, IAuthorizer authorizer, IWorkContextAccessor wca) { _auditTrailEventRepository = auditTrailEventRepository; + _authorizer = authorizer; + _wca = wca; } public void ExecuteRecipeStep(RecipeContext recipeContext) { @@ -20,6 +26,12 @@ namespace Orchard.AuditTrail.ImportExport { return; } + if (!_authorizer.Authorize(Permissions.ImportAuditTrail)) { + Logger.Warning("Blocked {0} from importing an audit trail because this user does not have the ImportauditTrail permission.", _wca.GetContext().CurrentUser.UserName); + recipeContext.Executed = false; + return; + } + foreach (var eventElement in recipeContext.RecipeStep.Step.Elements()) { var record = new AuditTrailEventRecord { EventName = eventElement.Attr("Name"), diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs index 1438e0d98..43008157d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Permissions.cs @@ -6,19 +6,23 @@ namespace Orchard.AuditTrail { public class Permissions : IPermissionProvider { public static readonly Permission ViewAuditTrail = new Permission { Description = "View audit trail", Name = "ViewAuditTrail" }; public static readonly Permission ManageAuditTrailSettings = new Permission { Description = "Manage audit trail settings", Name = "ManageAuditTrailSettings" }; + public static readonly Permission ImportAuditTrail = new Permission { Description = "Import audit trail", Name = "ImportAuditTrail" }; public virtual Feature Feature { get; set; } public IEnumerable GetPermissions() { yield return ViewAuditTrail; yield return ManageAuditTrailSettings; + yield return ImportAuditTrail; } public IEnumerable GetDefaultStereotypes() { - return new[] { - new PermissionStereotype { - Name = "Administrator", - Permissions = new[] {ViewAuditTrail, ManageAuditTrailSettings} + yield return new PermissionStereotype { + Name = "Administrator", + Permissions = new[] { + ViewAuditTrail, + ManageAuditTrailSettings, + /* Not even an administrator will get the ImportAuditTrail permission. */ } }; } From 236ecd2201bb43fbf3a7080fa966fb34d5ce0ed8 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 15 Jul 2014 23:56:31 -0700 Subject: [PATCH 081/116] Incremental work on #184. --- .../Orchard.AuditTrail/Helpers/XmlHelper.cs | 18 +++ .../Orchard.AuditTrail.csproj | 10 +- .../ContentTypeAuditTrailEventProvider.cs | 2 + .../GlobalContentDefinitionEditorEvents.cs | 103 +++++++++++++----- .../Services/Models/Diff.cs | 6 + .../Services/Models/DiffDictionary.cs | 5 + .../Shapes/AuditTrailEventShapeAlteration.cs | 23 ++++ .../Shapes/AuditTrailSettingsEventShape.cs | 30 +++-- .../ContentTypeSettingsUpdatedEventShape.cs | 54 +++++++++ .../Styles/audittrail-contenttype-event.css | 17 +++ ...Settings-EventsChanged.SummaryAdmin.cshtml | 3 +- ...nt-AuditTrailSettings-EventsChanged.cshtml | 1 - ...-ContentType-TypeDisplayNameUpdated.cshtml | 11 ++ ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 18 +++ ...ent-ContentType-TypeSettingsUpdated.cshtml | 33 +++++- .../Services/ContentDefinitionService.cs | 14 ++- .../IContentDefinitionEditorEvents.cs | 25 +++++ 17 files changed, 320 insertions(+), 53 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/XmlHelper.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Diff.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DiffDictionary.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailEventShapeAlteration.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/XmlHelper.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/XmlHelper.cs new file mode 100644 index 000000000..91fa09025 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/XmlHelper.cs @@ -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; + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 53aff618d..d7779269f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -84,6 +84,7 @@ + @@ -108,7 +109,7 @@ - + @@ -129,6 +130,8 @@ + +
@@ -169,6 +172,7 @@ + @@ -191,7 +195,11 @@ + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 1bac9f6fe..2ecf9ee52 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.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); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index 6b4216740..d5ef2dda3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -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 TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) { - var eventData = new Dictionary { - {"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 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 { + {"ContentTypeName", builder.Name}, + {"OldDisplayName", _oldContentTypeDisplayName}, + {"NewDisplayName", newDisplayName} + }; + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.TypeDisplayNameUpdated, eventData, contentTypeDefinition.Name); + } + + if (!AreEqual(newSettings, _oldContentTypeSettings)) { + var eventData = new Dictionary { + {"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 { {"ContentPartName", builder.Name}, {"ContentTypeName", builder.TypeName} }; RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.TypeName); - yield break; } - public override IEnumerable PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) { - var eventData = new Dictionary { - {"ContentPartName", builder.Name} - }; - RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); - yield break; - } + //public override void PartEditorUpdated(ContentPartDefinitionBuilder builder) { + // var eventData = new Dictionary { + // {"ContentPartName", builder.Name} + // }; + // RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); + //} - public override IEnumerable PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) { - var eventData = new Dictionary { - {"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 { + // {"ContentFieldName", builder.Name}, + // {"ContentFieldType", builder.FieldType}, + // {"ContentPartName", builder.PartName} + // }; + // RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName); + //} private void RecordContentTypeAuditTrail(string eventName, IDictionary eventData, string contentTypeName) { _auditTrailManager.CreateRecord(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 eventData, string contentPartName) { _auditTrailManager.CreateRecord(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); + } } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Diff.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Diff.cs new file mode 100644 index 000000000..e8634978e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Diff.cs @@ -0,0 +1,6 @@ +namespace Orchard.AuditTrail.Services.Models { + public class Diff { + public T OldValue { get; set; } + public T NewValue { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DiffDictionary.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DiffDictionary.cs new file mode 100644 index 000000000..720f7247a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/DiffDictionary.cs @@ -0,0 +1,5 @@ +using System.Collections.Generic; + +namespace Orchard.AuditTrail.Services.Models { + public class DiffDictionary : Dictionary> {} +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailEventShapeAlteration.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailEventShapeAlteration.cs new file mode 100644 index 000000000..f76afc01f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailEventShapeAlteration.cs @@ -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 : 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(EventName)) + return; + + OnAlterShape(context); + }); + } + + protected virtual void OnAlterShape(ShapeDisplayingContext context) {} + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs index 13514fea2..310bc138f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs @@ -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 { private readonly Work _auditTrailManager; public AuditTrailSettingsEventShape(Work 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.EventsChanged)) - return; + protected override string EventName { + get { return SettingsAuditTrailEventProvider.EventsChanged; } + } - var eventData = (IDictionary)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)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 GetDiffQuery(IEnumerable oldSettings, IEnumerable newSettings) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs new file mode 100644 index 000000000..0606fe42e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs @@ -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 { + 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)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 GetDiff(SettingsDictionary oldSettings, SettingsDictionary newSettings) { + var dictionary = new DiffDictionary(); + + BuildDiff(dictionary, newSettings, oldSettings); + BuildDiff(dictionary, oldSettings, newSettings); + + return dictionary; + } + + private static void BuildDiff(DiffDictionary 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 { + NewValue = settingA.Value, + OldValue = b + }; + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css new file mode 100644 index 000000000..08b085fd7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css @@ -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; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml index 3d1474c56..121cc0f2d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml @@ -3,7 +3,6 @@ var diff = (IList)Model.Diff; var descriptions = String.Join("
", diff.Select(x => T("{0} ({1}) was {2}", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text)); } - -
+
@Html.Raw(descriptions)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml index d12e7eeb7..8d40801fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml @@ -6,7 +6,6 @@ var diff = (IList)Model.Diff; var groups = diff.GroupBy(x => x.Descriptor.CategoryDescriptor.Name).OrderBy(x => x.Key.Text); } -
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml new file mode 100644 index 000000000..06c100842 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml @@ -0,0 +1,11 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var oldDisplayName = eventData.Get("OldDisplayName"); + var newDisplayName = eventData.Get("NewDisplayName"); +} + +
+ @T("The display name for the {0} content type was changed from {1} to {2}.", contentTypeName, oldDisplayName, newDisplayName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..2effc4849 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,18 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode("") : value; + } +} +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var diff = (DiffDictionary) Model.Diff; + var descriptions = String.Join("
", diff.Select(x => T("{0} was changed from {1} to {2}.", x.Key, ToFriendlyEmpty(x.Value.OldValue), ToFriendlyEmpty(x.Value.NewValue)).Text)); +} + +
+ @T("The following {0} settings were changed:", contentTypeName)
+ @Html.Raw(descriptions) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index 080f1f6e4..4abf0ccbc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -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) ? "" : value; + } +} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); + var differences = (DiffDictionary) Model.Diff; } - -
- @T("Settings for the {0} content type were updated.", contentTypeName) +
+

@T("The following {0} settings were changed", contentTypeName)

+
+ + + + + + + + + @foreach (var diff in differences) { + + + + + + } + +
@T("Setting")@T("From")@T("To")
@diff.Key@ToFriendlyEmpty(diff.Value.OldValue)@ToFriendlyEmpty(diff.Value.NewValue)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs index 3fd59f169..874ba40d7 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs @@ -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); }); } }); diff --git a/src/Orchard/ContentManagement/MetaData/IContentDefinitionEditorEvents.cs b/src/Orchard/ContentManagement/MetaData/IContentDefinitionEditorEvents.cs index 35af04092..28b504950 100644 --- a/src/Orchard/ContentManagement/MetaData/IContentDefinitionEditorEvents.cs +++ b/src/Orchard/ContentManagement/MetaData/IContentDefinitionEditorEvents.cs @@ -12,10 +12,19 @@ namespace Orchard.ContentManagement.MetaData { IEnumerable PartEditor(ContentPartDefinition definition); IEnumerable PartFieldEditor(ContentPartFieldDefinition definition); + + void TypeEditorUpdating(ContentTypeDefinitionBuilder builder); IEnumerable TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel); + void TypeEditorUpdated(ContentTypeDefinitionBuilder builder); + void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder); IEnumerable TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel); + void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder); + void PartEditorUpdating(ContentPartDefinitionBuilder builder); IEnumerable PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel); + void PartEditorUpdated(ContentPartDefinitionBuilder builder); + void PartFieldEditorUpdating(ContentPartFieldDefinitionBuilder builder); IEnumerable 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(); } + public virtual void TypeEditorUpdating(ContentTypeDefinitionBuilder builder) {} + public virtual IEnumerable TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) { return Enumerable.Empty(); } + public virtual void TypeEditorUpdated(ContentTypeDefinitionBuilder builder) { } + + public virtual void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder) {} + public virtual IEnumerable TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) { return Enumerable.Empty(); } + public virtual void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder) { } + + public virtual void PartEditorUpdating(ContentPartDefinitionBuilder builder) {} + public virtual IEnumerable PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) { return Enumerable.Empty(); } + public virtual void PartEditorUpdated(ContentPartDefinitionBuilder builder) { } + + public virtual void PartFieldEditorUpdating(ContentPartFieldDefinitionBuilder builder) {} + public virtual IEnumerable PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) { return Enumerable.Empty(); } + public virtual void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder) {} + protected static TemplateViewModel DefinitionTemplate(TModel model) { return DefinitionTemplate(model, typeof(TModel).Name, typeof(TModel).Name); } From 63c8bd1101cebabebf9316f837590f684698a048 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 17 Jul 2014 00:08:29 -0700 Subject: [PATCH 082/116] Incremental work on content type events. --- .../Helpers/SettingsDictionaryExtensions.cs | 39 ++++++++ .../Orchard.AuditTrail.csproj | 10 ++- .../ContentTypeAuditTrailEventProvider.cs | 4 +- .../GlobalContentDefinitionEditorEvents.cs | 88 +++++++++++++------ .../ContentPartSettingsUpdatedEventShape.cs | 29 ++++++ ...ntentTypeFieldSettingsUpdatedEventShape.cs | 29 ++++++ ...ontentTypePartSettingsUpdatedEventShape.cs | 29 ++++++ .../ContentTypeSettingsUpdatedEventShape.cs | 27 +----- .../Styles/audittrail-contenttype-event.css | 9 ++ ...rt-PartSettingsUpdated.SummaryAdmin.cshtml | 25 ++++++ ...ent-ContentPart-PartSettingsUpdated.cshtml | 37 ++++++-- ...e-FieldSettingsUpdated.SummaryAdmin.cshtml | 29 ++++++ ...nt-ContentType-FieldSettingsUpdated.cshtml | 40 +++++++++ ...pe-PartSettingsUpdated.SummaryAdmin.cshtml | 26 ++++++ ...ent-ContentType-PartSettingsUpdated.cshtml | 33 ++++++- ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 18 ++-- ...ent-ContentType-TypeSettingsUpdated.cshtml | 10 +-- .../Controllers/AdminController.cs | 10 ++- .../Services/ContentDefinitionService.cs | 2 + .../Builders/ContentPartDefinitionBuilder.cs | 2 +- .../ContentPartFieldDefinitionBuilder.cs | 2 + .../Builders/ContentTypeDefinitionBuilder.cs | 2 +- .../ContentTypePartDefinitionBuilder.cs | 2 + 23 files changed, 427 insertions(+), 75 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs new file mode 100644 index 000000000..4225c915e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs @@ -0,0 +1,39 @@ +using Orchard.AuditTrail.Services.Models; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.AuditTrail.Helpers { + public static class SettingsDictionaryExtensions { + public static DiffDictionary GetDiff(this SettingsDictionary oldSettings, SettingsDictionary newSettings) { + var dictionary = new DiffDictionary(); + + BuildDiff(dictionary, newSettings, oldSettings); + BuildDiff(dictionary, oldSettings, newSettings); + + return dictionary; + } + + private static void BuildDiff(DiffDictionary dictionary, SettingsDictionary settingsA, SettingsDictionary settingsB) { + + foreach (var settingA in settingsA) { + string oldValue, newValue; + + if (settingsB.ContainsKey(settingA.Key)) { + oldValue = settingA.Value; + newValue = settingsB[settingA.Key]; + } + else { + oldValue = settingA.Value; + newValue = settingsB[settingA.Key] = default(string); + + } + + if (oldValue != newValue) { + dictionary[settingA.Key] = new Diff { + NewValue = newValue, + OldValue = oldValue + }; + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index d7779269f..d4c5d67a7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -103,7 +103,7 @@ - + @@ -132,6 +132,10 @@ + + + + @@ -172,6 +176,7 @@ + @@ -196,6 +201,9 @@ + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs index 2ecf9ee52..14f47b509 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentTypeAuditTrailEventProvider.cs @@ -22,6 +22,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public const string TypeDisplayNameUpdated = "TypeDisplayNameUpdated"; public const string TypeSettingsUpdated = "TypeSettingsUpdated"; public const string PartSettingsUpdated = "PartSettingsUpdated"; + public const string FieldSettingsUpdated = "FieldSettingsUpdated"; public override void Describe(DescribeContext context) { context.For("ContentType", T("Content Type")) @@ -31,7 +32,8 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { .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); + .Event(this, PartSettingsUpdated, T("Part settings updated"), T("The settings of a content part on a content type were updated."), enableByDefault: true) + .Event(this, FieldSettingsUpdated, T("Field settings updated"), T("The settings of a content field on a content part on a content type were updated."), enableByDefault: true); context.QueryFilter(QueryFilter); context.DisplayFilter(DisplayFilter); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index d5ef2dda3..fddd6db9a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; +using System.Linq; 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.ContentTypes.ViewModels; using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { @@ -17,9 +17,13 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; private readonly IContentDefinitionService _contentDefinitionService; - private string _oldContentTypeDisplayName; - private SettingsDictionary _oldContentTypeSettings; private readonly ISettingsFormatter _settingsFormatter; + private string _oldContentTypeDisplayName; + private EditTypeViewModel _currentContentType; + private SettingsDictionary _oldContentTypeSettings; + private SettingsDictionary _oldContentTypePartSettings; + private SettingsDictionary _oldContentPartFieldSettings; + private SettingsDictionary _oldPartSettings; public GlobalContentDefinitionEditorEvents( IAuditTrailManager auditTrailManager, @@ -35,6 +39,7 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public override void TypeEditorUpdating(ContentTypeDefinitionBuilder definition) { var contentType = _contentDefinitionService.GetType(definition.Name); + _currentContentType = contentType; _oldContentTypeDisplayName = contentType.DisplayName; _oldContentTypeSettings = new SettingsDictionary(contentType.Settings); } @@ -64,33 +69,66 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { } public override void TypePartEditorUpdating(ContentTypePartDefinitionBuilder builder) { - // TODO: record current values + var contentTypeDefinition = _contentDefinitionService.GetType(builder.TypeName); + var contentPart = contentTypeDefinition.Parts.Single(x => x.PartDefinition.Name == builder.Name); + _oldContentTypePartSettings = contentPart.Settings; } public override void TypePartEditorUpdated(ContentTypePartDefinitionBuilder builder) { - // TODO: compare old values with new values. - var eventData = new Dictionary { - {"ContentPartName", builder.Name}, - {"ContentTypeName", builder.TypeName} - }; - RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.TypeName); + var contentTypePartDefinition = builder.Build(); + var newSettings = contentTypePartDefinition.Settings; + + if (!AreEqual(newSettings, _oldContentTypePartSettings)) { + var eventData = new Dictionary { + {"ContentPartName", builder.Name}, + {"ContentTypeName", builder.TypeName}, + {"OldSettings", ToXml(_oldContentTypePartSettings)}, + {"NewSettings", ToXml(newSettings)} + }; + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.TypeName); + } } - //public override void PartEditorUpdated(ContentPartDefinitionBuilder builder) { - // var eventData = new Dictionary { - // {"ContentPartName", builder.Name} - // }; - // RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); - //} + public override void PartFieldEditorUpdating(ContentPartFieldDefinitionBuilder builder) { + var contentPart = _contentDefinitionService.GetPart(builder.PartName); + var contentField = contentPart.Fields.Single(x => x.Name == builder.Name); + _oldContentPartFieldSettings = contentField.Settings; + } - //public override void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder) { - // var eventData = new Dictionary { - // {"ContentFieldName", builder.Name}, - // {"ContentFieldType", builder.FieldType}, - // {"ContentPartName", builder.PartName} - // }; - // RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName); - //} + public override void PartFieldEditorUpdated(ContentPartFieldDefinitionBuilder builder) { + var contentPartFieldDefinition = builder.Build(); + var newSettings = contentPartFieldDefinition.Settings; + + if (!AreEqual(newSettings, _oldContentPartFieldSettings)) { + var eventData = new Dictionary { + {"ContentFieldName", builder.Name}, + {"ContentPartName", builder.PartName}, + {"ContentTypeName", _currentContentType.Name}, + {"OldSettings", ToXml(_oldContentPartFieldSettings)}, + {"NewSettings", ToXml(newSettings)} + }; + RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.FieldSettingsUpdated, eventData, _currentContentType.Name); + } + } + + public override void PartEditorUpdating(ContentPartDefinitionBuilder builder) { + var contentPart = _contentDefinitionService.GetPart(builder.Name); + _oldPartSettings = contentPart.Settings; + } + + public override void PartEditorUpdated(ContentPartDefinitionBuilder builder) { + var contentPartDefinition = builder.Build(); + var newSettings = contentPartDefinition.Settings; + + if (!AreEqual(newSettings, _oldPartSettings)) { + var eventData = new Dictionary { + {"ContentPartName", builder.Name}, + {"OldSettings", ToXml(_oldPartSettings)}, + {"NewSettings", ToXml(newSettings)} + }; + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); + } + } private void RecordContentTypeAuditTrail(string eventName, IDictionary eventData, string contentTypeName) { _auditTrailManager.CreateRecord(eventName, _wca.GetContext().CurrentUser, properties: null, eventData: eventData, eventFilterKey: "contenttype", eventFilterData: contentTypeName); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs new file mode 100644 index 000000000..348b752c1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.ContentManagement.MetaData.Services; +using Orchard.DisplayManagement.Implementation; + +namespace Orchard.AuditTrail.Shapes { + public class ContentPartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { + private readonly ISettingsFormatter _settingsFormatter; + public ContentPartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { + _settingsFormatter = settingsFormatter; + } + + protected override string EventName { + get { return ContentPartAuditTrailEventProvider.PartSettingsUpdated; } + } + + protected override void OnAlterShape(ShapeDisplayingContext context) { + var eventData = (IDictionary)context.Shape.EventData; + var oldSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["OldSettings"])); + var newSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["NewSettings"])); + var diff = oldSettings.GetDiff(newSettings); + + context.Shape.OldSettings = oldSettings; + context.Shape.NewSettings = newSettings; + context.Shape.Diff = diff; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs new file mode 100644 index 000000000..a3ea08f16 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.ContentManagement.MetaData.Services; +using Orchard.DisplayManagement.Implementation; + +namespace Orchard.AuditTrail.Shapes { + public class ContentTypeFieldSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { + private readonly ISettingsFormatter _settingsFormatter; + public ContentTypeFieldSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { + _settingsFormatter = settingsFormatter; + } + + protected override string EventName { + get { return ContentTypeAuditTrailEventProvider.FieldSettingsUpdated; } + } + + protected override void OnAlterShape(ShapeDisplayingContext context) { + var eventData = (IDictionary)context.Shape.EventData; + var oldSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["OldSettings"])); + var newSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["NewSettings"])); + var diff = oldSettings.GetDiff(newSettings); + + context.Shape.OldSettings = oldSettings; + context.Shape.NewSettings = newSettings; + context.Shape.Diff = diff; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs new file mode 100644 index 000000000..cb3554a5c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Orchard.AuditTrail.Helpers; +using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.ContentManagement.MetaData.Services; +using Orchard.DisplayManagement.Implementation; + +namespace Orchard.AuditTrail.Shapes { + public class ContentTypePartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { + private readonly ISettingsFormatter _settingsFormatter; + public ContentTypePartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { + _settingsFormatter = settingsFormatter; + } + + protected override string EventName { + get { return ContentTypeAuditTrailEventProvider.PartSettingsUpdated; } + } + + protected override void OnAlterShape(ShapeDisplayingContext context) { + var eventData = (IDictionary)context.Shape.EventData; + var oldSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["OldSettings"])); + var newSettings = _settingsFormatter.Map(XmlHelper.Parse((string)eventData["NewSettings"])); + var diff = oldSettings.GetDiff(newSettings); + + context.Shape.OldSettings = oldSettings; + context.Shape.NewSettings = newSettings; + context.Shape.Diff = diff; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs index 0606fe42e..e01fa8de0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs @@ -1,8 +1,6 @@ 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; @@ -21,34 +19,11 @@ namespace Orchard.AuditTrail.Shapes { var eventData = (IDictionary)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); + var diff = oldSettings.GetDiff(newSettings); context.Shape.OldSettings = oldSettings; context.Shape.NewSettings = newSettings; context.Shape.Diff = diff; } - - private static DiffDictionary GetDiff(SettingsDictionary oldSettings, SettingsDictionary newSettings) { - var dictionary = new DiffDictionary(); - - BuildDiff(dictionary, newSettings, oldSettings); - BuildDiff(dictionary, oldSettings, newSettings); - - return dictionary; - } - - private static void BuildDiff(DiffDictionary 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 { - NewValue = settingA.Value, - OldValue = b - }; - } - } - } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css index 08b085fd7..819cdf65d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css @@ -14,4 +14,13 @@ section.audittrail-contenttype-event table.items { section.audittrail-contenttype-event table.items thead th { font-weight: bold; +} + +section.audittrail-contenttype-event ul { + list-style-type: square; + margin-left: 1.5em; +} + +section.audittrail-contenttype-event ul li { + padding-left: 0.5em; } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..8ba2ea59e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,25 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; + } +} +@{ + var eventData = (IDictionary)Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var diff = (DiffDictionary)Model.Diff; +} +
+
@T("Settings for {0} were updated:", contentPartName)
+
    + @foreach (var setting in diff) { +
  • + @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) +
  • + } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index d22fcf49a..b6935237e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -1,9 +1,36 @@ @using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models @{ - var eventData = (IDictionary) Model.EventData; - var contentPartName = eventData.Get("ContentPartName"); + Style.Include("audittrail-contenttype-event.css"); } - -
- @T("Settings for the {0} content part were updated.", contentPartName) +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; + } +} +@{ + var eventData = (IDictionary)Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var diff = (DiffDictionary)Model.Diff; +} +
+

@T("Settings for {0} were updated:", contentPartName)

+ + + + + + + + + + @foreach (var setting in diff) { + + + + + + } + +
@T("Setting")@T("From")@T("To")
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..7d6b42398 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,29 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; + } +} +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); + var diff = (DiffDictionary)Model.Diff; + var isImplicitPart = contentTypeName == contentPartName; + var captionTemplate = isImplicitPart ? "Settings for {0} attached the {1} content type were updated:" : "Settings for {0} attached to {1} of the {2} content type were updated:"; +} +
+
@T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
+
    + @foreach (var setting in diff) { +
  • + @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) +
  • + } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml new file mode 100644 index 000000000..27bce0b92 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml @@ -0,0 +1,40 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? T("").Text : value; + } +} +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); + var diff = (DiffDictionary)Model.Diff; + var isImplicitPart = contentTypeName == contentPartName; + var captionTemplate = isImplicitPart ? "Settings for {0} attached the {1} content type were updated:" : "Settings for {0} attached to {1} of the {2} content type were updated:"; +} +
+

@T(captionTemplate, contentFieldName, contentPartName, contentTypeName)

+ + + + + + + + + + @foreach (var setting in diff) { + + + + + + } + +
@T("Setting")@T("From")@T("To")
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..52360ad99 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,26 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; + } +} +@{ + var eventData = (IDictionary) Model.EventData; + var contentTypeName = eventData.Get("ContentTypeName"); + var contentPartName = eventData.Get("ContentPartName"); + var diff = (DiffDictionary)Model.Diff; +} +
+
@T("Settings for {0} attached to the {1} content type were updated:", contentPartName, contentTypeName)
+
    + @foreach (var setting in diff) { +
  • + @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) +
  • + } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index c9f146706..5cbc92ef0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -1,10 +1,37 @@ @using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} +@functions { + string ToFriendlyEmpty(string value) { + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; + } +} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); var contentPartName = eventData.Get("ContentPartName"); + var diff = (DiffDictionary)Model.Diff; } - -
- @T("Settings for the {0} content part attached to the {1} content type were updated.", contentPartName, contentTypeName) +
+

@T("Settings for {0} attached to the {1} content type were updated:", contentPartName, contentTypeName)

+ + + + + + + + + + @foreach (var setting in diff) { + + + + + + } + +
@T("Setting")@T("From")@T("To")
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index 2effc4849..0bcef5e06 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -1,18 +1,26 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contenttype-event.css"); +} @functions { string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode("") : value; + return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; } } @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); var diff = (DiffDictionary) Model.Diff; - var descriptions = String.Join("
", diff.Select(x => T("{0} was changed from {1} to {2}.", x.Key, ToFriendlyEmpty(x.Value.OldValue), ToFriendlyEmpty(x.Value.NewValue)).Text)); } -
- @T("The following {0} settings were changed:", contentTypeName)
- @Html.Raw(descriptions) +
+ @T("The following {0} settings were changed:", contentTypeName)
+
    + @foreach (var setting in diff) { +
  • + @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) +
  • + } +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index 4abf0ccbc..f773fb1fc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -11,7 +11,7 @@ @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); - var differences = (DiffDictionary) Model.Diff; + var diff = (DiffDictionary) Model.Diff; }

@T("The following {0} settings were changed", contentTypeName)

@@ -24,11 +24,11 @@ - @foreach (var diff in differences) { + @foreach (var setting in diff) { - @diff.Key - @ToFriendlyEmpty(diff.Value.OldValue) - @ToFriendlyEmpty(diff.Value.NewValue) + @setting.Key + @ToFriendlyEmpty(setting.Value.OldValue) + @ToFriendlyEmpty(setting.Value.NewValue) } diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs index fb851d967..9fe315ecf 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs @@ -621,8 +621,14 @@ namespace Orchard.ContentTypes.Controllers { return HttpNotFound(); } - field.DisplayName = viewModel.DisplayName; - _contentDefinitionManager.StorePartDefinition(partViewModel._Definition); + _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => { + partBuilder.WithField(viewModel.Name, fieldBuilder => { + fieldBuilder.WithDisplayName(viewModel.DisplayName); + }); + }); + + //field.DisplayName = viewModel.DisplayName; + //_contentDefinitionManager.StorePartDefinition(partViewModel._Definition); Services.Notifier.Information(T("Display name changed to {0}.", viewModel.DisplayName)); diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs index 874ba40d7..0565ca92d 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs @@ -245,7 +245,9 @@ namespace Orchard.ContentTypes.Services { public void AlterPart(EditPartViewModel partViewModel, IUpdateModel updateModel) { var updater = new Updater(updateModel); _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => { + _contentDefinitionEditorEvents.PartEditorUpdating(partBuilder); partViewModel.Templates = _contentDefinitionEditorEvents.PartEditorUpdate(partBuilder, updater); + _contentDefinitionEditorEvents.PartEditorUpdated(partBuilder); }); } diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs index 6fd9a0853..d9965490f 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs @@ -86,7 +86,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { _partDefinition = part; } - public ContentPartFieldDefinition Build() { + public override ContentPartFieldDefinition Build() { return new ContentPartFieldDefinition(_fieldDefinition, _fieldName, _settings); } diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs index f975cbbc1..f748a0a4d 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartFieldDefinitionBuilder.cs @@ -25,5 +25,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { public abstract ContentPartFieldDefinitionBuilder OfType(ContentFieldDefinition fieldDefinition); public abstract ContentPartFieldDefinitionBuilder OfType(string fieldType); + + public abstract ContentPartFieldDefinition Build(); } } \ No newline at end of file diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs index 7b7199139..50eda2d78 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs @@ -86,7 +86,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { _partDefinition = part.PartDefinition; } - public ContentTypePartDefinition Build() { + public override ContentTypePartDefinition Build() { return new ContentTypePartDefinition(_partDefinition, _settings); } } diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs index 35b73008e..b8b9a1d23 100644 --- a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypePartDefinitionBuilder.cs @@ -18,5 +18,7 @@ namespace Orchard.ContentManagement.MetaData.Builders { _settings[name] = value; return this; } + + public abstract ContentTypePartDefinition Build(); } } From 02f5a29f0cf57f9457bbda3f3d3501ab616c4d58 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 17 Jul 2014 18:45:05 -0700 Subject: [PATCH 083/116] Implementing content part field change events and audit trail provider. --- .../Helpers/SettingsDictionaryExtensions.cs | 5 +++++ .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 12 ++++++------ .../AuditTrail}/AuditTrailFilterShapes.cs | 2 +- .../AuditTrail}/AuditTrailSettingsEventShape.cs | 4 ++-- .../GlobalContentDefinitionEditorEvents.cs | 4 ++-- .../Shapes/ContentPartSettingsUpdatedEventShape.cs | 4 ++-- .../ContentTypeFieldSettingsUpdatedEventShape.cs | 11 +++++++---- .../ContentTypePartSettingsUpdatedEventShape.cs | 4 ++-- .../Shapes/ContentTypeSettingsUpdatedEventShape.cs | 4 ++-- ...railEvent-ContentPart-FieldSettingsUpdated.cshtml | 4 +++- .../Controllers/AdminController.cs | 9 +-------- .../Services/ContentDefinitionService.cs | 10 ++++++++++ .../Services/IContentDefinitionService.cs | 1 + 13 files changed, 44 insertions(+), 30 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{Shapes => Providers/AuditTrail}/AuditTrailFilterShapes.cs (90%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{Shapes => Providers/AuditTrail}/AuditTrailSettingsEventShape.cs (96%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Providers/ContentDefinition}/Shapes/ContentPartSettingsUpdatedEventShape.cs (92%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Providers/ContentDefinition}/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs (70%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Providers/ContentDefinition}/Shapes/ContentTypePartSettingsUpdatedEventShape.cs (92%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/{ => Providers/ContentDefinition}/Shapes/ContentTypeSettingsUpdatedEventShape.cs (92%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs index 4225c915e..def7a168f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/SettingsDictionaryExtensions.cs @@ -3,6 +3,11 @@ using Orchard.ContentManagement.MetaData.Models; namespace Orchard.AuditTrail.Helpers { public static class SettingsDictionaryExtensions { + + public static string Get(this SettingsDictionary settings, string key) { + return settings.ContainsKey(key) ? settings[key] : null; + } + public static DiffDictionary GetDiff(this SettingsDictionary oldSettings, SettingsDictionary newSettings) { var dictionary = new DiffDictionary(); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index d4c5d67a7..8dd0c2763 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -199,13 +199,13 @@ - + - - - - - + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailFilterShapes.cs similarity index 90% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailFilterShapes.cs index c7457083d..17ead5111 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailFilterShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailFilterShapes.cs @@ -1,7 +1,7 @@ using System.IO; using Orchard.DisplayManagement; -namespace Orchard.AuditTrail.Shapes { +namespace Orchard.AuditTrail.Providers.AuditTrail { public class AuditTrailFilterShapes : IDependency { [Shape] public void AuditTrailFilterDisplay(dynamic Shape, dynamic Display, TextWriter Output) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs similarity index 96% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs index 310bc138f..8eab467fc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/AuditTrailSettingsEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; using System.Linq; using Orchard.AuditTrail.Models; -using Orchard.AuditTrail.Providers.AuditTrail; using Orchard.AuditTrail.Services; +using Orchard.AuditTrail.Shapes; using Orchard.AuditTrail.ViewModels; using Orchard.DisplayManagement.Implementation; using Orchard.Environment; -namespace Orchard.AuditTrail.Shapes { +namespace Orchard.AuditTrail.Providers.AuditTrail { public class AuditTrailSettingsEventShape : AuditTrailEventShapeAlteration { private readonly Work _auditTrailManager; public AuditTrailSettingsEventShape(Work auditTrailManager) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index fddd6db9a..c790fb513 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; +using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Services; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Builders; @@ -103,11 +104,10 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { var eventData = new Dictionary { {"ContentFieldName", builder.Name}, {"ContentPartName", builder.PartName}, - {"ContentTypeName", _currentContentType.Name}, {"OldSettings", ToXml(_oldContentPartFieldSettings)}, {"NewSettings", ToXml(newSettings)} }; - RecordContentTypeAuditTrail(ContentTypeAuditTrailEventProvider.FieldSettingsUpdated, eventData, _currentContentType.Name); + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.FieldSettingsUpdated, eventData, builder.PartName); } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentPartSettingsUpdatedEventShape.cs similarity index 92% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentPartSettingsUpdatedEventShape.cs index 348b752c1..6c147b6ad 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentPartSettingsUpdatedEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentPartSettingsUpdatedEventShape.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using Orchard.AuditTrail.Helpers; -using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.AuditTrail.Shapes; using Orchard.ContentManagement.MetaData.Services; using Orchard.DisplayManagement.Implementation; -namespace Orchard.AuditTrail.Shapes { +namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes { public class ContentPartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { private readonly ISettingsFormatter _settingsFormatter; public ContentPartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs similarity index 70% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs index a3ea08f16..db7a7a9e9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeFieldSettingsUpdatedEventShape.cs @@ -1,18 +1,19 @@ using System.Collections.Generic; using Orchard.AuditTrail.Helpers; -using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.AuditTrail.Shapes; +using Orchard.ContentManagement.MetaData.Models; using Orchard.ContentManagement.MetaData.Services; using Orchard.DisplayManagement.Implementation; -namespace Orchard.AuditTrail.Shapes { - public class ContentTypeFieldSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { +namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes { + public class ContentTypeFieldSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { private readonly ISettingsFormatter _settingsFormatter; public ContentTypeFieldSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { _settingsFormatter = settingsFormatter; } protected override string EventName { - get { return ContentTypeAuditTrailEventProvider.FieldSettingsUpdated; } + get { return ContentPartAuditTrailEventProvider.FieldSettingsUpdated; } } protected override void OnAlterShape(ShapeDisplayingContext context) { @@ -22,7 +23,9 @@ namespace Orchard.AuditTrail.Shapes { var diff = oldSettings.GetDiff(newSettings); context.Shape.OldSettings = oldSettings; + context.Shape.OldDisplayName = oldSettings.Get(ContentPartFieldDefinition.DisplayNameKey); context.Shape.NewSettings = newSettings; + context.Shape.NewDisplayName = newSettings.Get(ContentPartFieldDefinition.DisplayNameKey); context.Shape.Diff = diff; } } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypePartSettingsUpdatedEventShape.cs similarity index 92% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypePartSettingsUpdatedEventShape.cs index cb3554a5c..7240b21a5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypePartSettingsUpdatedEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypePartSettingsUpdatedEventShape.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using Orchard.AuditTrail.Helpers; -using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.AuditTrail.Shapes; using Orchard.ContentManagement.MetaData.Services; using Orchard.DisplayManagement.Implementation; -namespace Orchard.AuditTrail.Shapes { +namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes { public class ContentTypePartSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { private readonly ISettingsFormatter _settingsFormatter; public ContentTypePartSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeSettingsUpdatedEventShape.cs similarity index 92% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeSettingsUpdatedEventShape.cs index e01fa8de0..5929e6d8d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Shapes/ContentTypeSettingsUpdatedEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/Shapes/ContentTypeSettingsUpdatedEventShape.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using Orchard.AuditTrail.Helpers; -using Orchard.AuditTrail.Providers.ContentDefinition; +using Orchard.AuditTrail.Shapes; using Orchard.ContentManagement.MetaData.Services; using Orchard.DisplayManagement.Implementation; -namespace Orchard.AuditTrail.Shapes { +namespace Orchard.AuditTrail.Providers.ContentDefinition.Shapes { public class ContentTypeSettingsUpdatedEventShape : AuditTrailEventShapeAlteration { private readonly ISettingsFormatter _settingsFormatter; public ContentTypeSettingsUpdatedEventShape(ISettingsFormatter settingsFormatter) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml index 5edd0a3fb..04fe1f0a8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml @@ -3,8 +3,10 @@ var eventData = (IDictionary) Model.EventData; var contentPartName = eventData.Get("ContentPartName"); var contentFieldName = eventData.Get("ContentFieldName"); + var oldDisplayName = (string)Model.OldDisplayName; + var newDisplayName = (string)Model.NewDisplayName; }
- @T("Settings for the {0} content field of the {1} content part were updated.", contentFieldName, contentPartName) + @T("The {0} content field of the {1} content part was renamed from {2} to {3}.", contentFieldName, contentPartName, oldDisplayName, newDisplayName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs index 9fe315ecf..4c2192a38 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs @@ -621,14 +621,7 @@ namespace Orchard.ContentTypes.Controllers { return HttpNotFound(); } - _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => { - partBuilder.WithField(viewModel.Name, fieldBuilder => { - fieldBuilder.WithDisplayName(viewModel.DisplayName); - }); - }); - - //field.DisplayName = viewModel.DisplayName; - //_contentDefinitionManager.StorePartDefinition(partViewModel._Definition); + _contentDefinitionService.AlterField(partViewModel, viewModel); Services.Notifier.Information(T("Display name changed to {0}.", viewModel.DisplayName)); diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs index 0565ca92d..dc55cdc8a 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs @@ -294,6 +294,16 @@ namespace Orchard.ContentTypes.Services { }); } + public void AlterField(EditPartViewModel partViewModel, EditFieldNameViewModel fieldViewModel) { + _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => { + partBuilder.WithField(fieldViewModel.Name, fieldBuilder => { + _contentDefinitionEditorEvents.PartFieldEditorUpdating(fieldBuilder); + fieldBuilder.WithDisplayName(fieldViewModel.DisplayName); + _contentDefinitionEditorEvents.PartFieldEditorUpdated(fieldBuilder); + }); + }); + } + public string GenerateContentTypeNameFromDisplayName(string displayName) { displayName = displayName.ToSafeName(); diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs index a7ee5136d..bbf5057c9 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs @@ -26,5 +26,6 @@ namespace Orchard.ContentTypes.Services { void AddFieldToPart(string fieldName, string fieldTypeName, string partName); void AddFieldToPart(string fieldName, string displayName, string fieldTypeName, string partName); void RemoveFieldFromPart(string fieldName, string partName); + void AlterField(EditPartViewModel partViewModel, EditFieldNameViewModel fieldViewModel); } } \ No newline at end of file From de2dc60587513adbc62989d1dd6c35accb8cff1b Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 19 Jul 2014 19:57:03 +0200 Subject: [PATCH 084/116] #190 Fixing content part event descriptions. --- .../ContentDefinition/ContentPartAuditTrailEventProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs index 5d8e6348e..de375450d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/ContentPartAuditTrailEventProvider.cs @@ -15,8 +15,8 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public override void Describe(DescribeContext context) { context.For("ContentPart", T("Content Parts")) - .Event(this, Created, T("Created"), T("A content type was created."), enableByDefault: true) - .Event(this, Removed, T("Removed"), T("A content type was removed."), enableByDefault: true) + .Event(this, Created, T("Created"), T("A content part was created."), enableByDefault: true) + .Event(this, Removed, T("Removed"), T("A content part was removed."), enableByDefault: true) .Event(this, DescriptionChanged, T("Description changed"), T("A content part description was changed."), enableByDefault: true) .Event(this, FieldAdded, T("Field added"), T("A field was added to a content part."), enableByDefault: true) .Event(this, FieldRemoved, T("Field removed"), T("A field was removed from a content part."), enableByDefault: true) From 359c765109af4d612f2465597caaf5d4ad3718e9 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 19 Jul 2014 20:31:14 +0200 Subject: [PATCH 085/116] #187 Displaying changes only for the trimmin settings that actually changed. Improved some display texts and renamed some classes. --- .../Handlers/AuditTrailSettingsPartHandler.cs | 4 ++-- .../AuditTrailTrimmingSettingsPartHandler.cs | 4 ++-- .../Orchard.AuditTrail.csproj | 4 ++-- ....cs => AuditTrailSettingsEventProvider.cs} | 4 ++-- .../AuditTrailSettingsEventShape.cs | 22 ++++++++++--------- ...uditTrailTrimmingSettingsEventProvider.cs} | 4 ++-- ...Settings-EventsChanged.SummaryAdmin.cshtml | 2 +- ...ailSettings-TrimmingSettingsChanged.cshtml | 8 +++++-- 8 files changed, 29 insertions(+), 23 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/{SettingsAuditTrailEventProvider.cs => AuditTrailSettingsEventProvider.cs} (73%) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/{TrimmingSettingsAuditTrailEventProvider.cs => AuditTrailTrimmingSettingsEventProvider.cs} (77%) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs index 0f95c1c0d..2d5655b21 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailSettingsPartHandler.cs @@ -55,8 +55,8 @@ namespace Orchard.AuditTrail.Handlers { if (newEventSettings == _oldEventSettings) return; - _auditTrailManager.CreateRecord( - eventName: SettingsAuditTrailEventProvider.EventsChanged, + _auditTrailManager.CreateRecord( + eventName: AuditTrailSettingsEventProvider.EventsChanged, eventData: new Dictionary { {"OldSettings", _oldEventSettings}, {"NewSettings", newEventSettings} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs index 374cffe45..7d3870bca 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Handlers/AuditTrailTrimmingSettingsPartHandler.cs @@ -43,8 +43,8 @@ namespace Orchard.AuditTrail.Handlers { if (newRetentionPeriod == _oldRetentionPeriod && newMinimumRunInterval == _oldMinimumRunInterval) return; - _auditTrailManager.CreateRecord( - eventName: TrimmingSettingsAuditTrailEventProvider.TrimmingSettingsChanged, + _auditTrailManager.CreateRecord( + eventName: AuditTrailTrimmingSettingsEventProvider.TrimmingSettingsChanged, user: _wca.GetContext().CurrentUser, eventData: new Dictionary { {"OldRetentionPeriod", _oldRetentionPeriod}, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 8dd0c2763..f3b8d567a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -184,8 +184,8 @@ - - + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventProvider.cs similarity index 73% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventProvider.cs index 94ff07b21..f3e8ed1a1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/SettingsAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventProvider.cs @@ -2,13 +2,13 @@ using Orchard.AuditTrail.Services.Models; namespace Orchard.AuditTrail.Providers.AuditTrail { - public class SettingsAuditTrailEventProvider : AuditTrailEventProviderBase { + public class AuditTrailSettingsEventProvider : AuditTrailEventProviderBase { public const string EventsChanged = "EventsChanged"; public override void Describe(DescribeContext context) { context.For("AuditTrailSettings", T("Audit Trail Settings")) - .Event(this, EventsChanged, T("Events changed"), T("Audit trail event settings were changed."), enableByDefault: true, isMandatory: true); + .Event(this, EventsChanged, T("Events changed"), T("The audit trail event settings were changed."), enableByDefault: true, isMandatory: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs index 8eab467fc..201519c3a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailSettingsEventShape.cs @@ -8,14 +8,15 @@ using Orchard.DisplayManagement.Implementation; using Orchard.Environment; namespace Orchard.AuditTrail.Providers.AuditTrail { - public class AuditTrailSettingsEventShape : AuditTrailEventShapeAlteration { + public class AuditTrailSettingsEventShape : AuditTrailEventShapeAlteration { private readonly Work _auditTrailManager; + public AuditTrailSettingsEventShape(Work auditTrailManager) { _auditTrailManager = auditTrailManager; } protected override string EventName { - get { return SettingsAuditTrailEventProvider.EventsChanged; } + get { return AuditTrailSettingsEventProvider.EventsChanged; } } protected override void OnAlterShape(ShapeDisplayingContext context) { @@ -31,14 +32,15 @@ namespace Orchard.AuditTrail.Providers.AuditTrail { private IEnumerable GetDiffQuery(IEnumerable oldSettings, IEnumerable newSettings) { var oldDictionary = oldSettings.ToDictionary(x => x.EventName); - - return from newSetting in newSettings - let oldSetting = oldDictionary.ContainsKey(newSetting.EventName) ? oldDictionary[newSetting.EventName] : default(AuditTrailEventSetting) - where oldSetting == null || oldSetting.IsEnabled != newSetting.IsEnabled - select new AuditTrailEventDescriptorSettingViewModel { - Setting = newSetting, - Descriptor = _auditTrailManager.Value.DescribeEvent(newSetting.EventName) - }; + + return + from newSetting in newSettings + let oldSetting = oldDictionary.ContainsKey(newSetting.EventName) ? oldDictionary[newSetting.EventName] : default(AuditTrailEventSetting) + where oldSetting == null || oldSetting.IsEnabled != newSetting.IsEnabled + select new AuditTrailEventDescriptorSettingViewModel { + Setting = newSetting, + Descriptor = _auditTrailManager.Value.DescribeEvent(newSetting.EventName) + }; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailTrimmingSettingsEventProvider.cs similarity index 77% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailTrimmingSettingsEventProvider.cs index ffdc2760d..f7a97a0fc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/TrimmingSettingsAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/AuditTrail/AuditTrailTrimmingSettingsEventProvider.cs @@ -4,13 +4,13 @@ using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.AuditTrail { [OrchardFeature("Orchard.AuditTrail.Trimming")] - public class TrimmingSettingsAuditTrailEventProvider : AuditTrailEventProviderBase { + public class AuditTrailTrimmingSettingsEventProvider : AuditTrailEventProviderBase { public const string TrimmingSettingsChanged = "TrimmingSettingsChanged"; public override void Describe(DescribeContext context) { context.For("AuditTrailSettings", T("Audit Trail Settings")) - .Event(this, TrimmingSettingsChanged, T("Trimming settings changed"), T("Audit trail trimming settings were changed."), enableByDefault: true); + .Event(this, TrimmingSettingsChanged, T("Trimming settings changed"), T("The audit trail trimming settings were changed."), enableByDefault: true); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml index 121cc0f2d..442730424 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml @@ -1,7 +1,7 @@ @using Orchard.AuditTrail.ViewModels @{ var diff = (IList)Model.Diff; - var descriptions = String.Join("
", diff.Select(x => T("{0} ({1}) was {2}", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text)); + var descriptions = String.Join("
", diff.Select(x => T("The {0} event in category {1} was {2}.", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text)); }
@Html.Raw(descriptions) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index 9ad57852b..84a305e65 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -8,6 +8,10 @@ }
-
@T("Trimming retention period changed from {0} to {1}", T.Plural("1 day", "{0} days", oldRetentionPeriod), T.Plural("1 day", "{0} days", newRetentionPeriod))
-
@T("Minimum run interval changed from {0} to {1}", T.Plural("1 hour", "{0} hours", oldMinimumRunInterval), T.Plural("1 hour", "{0} hours", newMinimumRunInterval))
+ @if (newRetentionPeriod != oldRetentionPeriod) { +
@T("The trimming retention period was changed from {0} to {1}.", T.Plural("1 day", "{0} days", oldRetentionPeriod), T.Plural("1 day", "{0} days", newRetentionPeriod))
+ } + @if (newMinimumRunInterval != oldMinimumRunInterval) { +
@T("The minimum trimming run interval was changed from {0} to {1}.", T.Plural("1 hour", "{0} hours", oldMinimumRunInterval), T.Plural("1 hour", "{0} hours", newMinimumRunInterval))
+ }
\ No newline at end of file From bdb10182df53de70e6b9dd35a540e308c599b6db Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 19 Jul 2014 13:42:58 -0700 Subject: [PATCH 086/116] #174: Loading the latest content item version instead of the published version. --- .../Providers/Content/ContentAuditTrailEventShapes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs index 5cb577faa..00e56bb67 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -26,7 +26,7 @@ namespace Orchard.AuditTrail.Providers.Content { var eventData = (IDictionary)context.Shape.EventData; var contentItemId = eventData.Get("ContentId"); var previousContentItemVersionId = eventData.Get("PreviousVersionId"); - var contentItem = _contentManager.Value.Get(contentItemId); + var contentItem = _contentManager.Value.Get(contentItemId, VersionOptions.Latest); var previousVersion = previousContentItemVersionId > 0 ? _contentManager.Value.Get(contentItemId, VersionOptions.VersionRecord(previousContentItemVersionId)) : default(ContentItem); if (previousVersion != null) { From a39d1eb4921a2e23e500b1e371ab19a18029abf5 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sat, 19 Jul 2014 23:32:51 +0200 Subject: [PATCH 087/116] #191 Fixed handling of added nodes in diffgram analysis. --- .../Providers/Content/DiffGramAnalyzer.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index 5eb08b657..bd22deaa9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -61,6 +61,7 @@ namespace Orchard.AuditTrail.Providers.Content { }; } else { + var elementName = currentElement.Name.ToString(); var originalContent = currentElement.Value; var currentContent = reader.ReadElementContentAsString(); @@ -69,16 +70,26 @@ namespace Orchard.AuditTrail.Providers.Content { yield return new DiffNode { Type = DiffType.Change, - Context = currentElement.Name.ToString(), + Context = BuildContextName(stack, elementName), Previous = originalContent, Current = currentContent }; } break; case "add": + string nodeName = reader.GetAttribute("name"); + string addedContent = null; reader.Read(); - var addedElementContent = reader.ReadElementContentAsString(); - yield return new DiffNode { Type = DiffType.Addition, Context = reader.Name, Current = addedElementContent }; + if (reader.NodeType != XmlNodeType.EndElement) { + nodeName = reader.Name; + addedContent = reader.ReadElementContentAsString(); + } + yield return + new DiffNode { + Type = DiffType.Addition, + Context = BuildContextName(stack, nodeName), + Current = addedContent + }; break; } } @@ -93,8 +104,8 @@ namespace Orchard.AuditTrail.Providers.Content { } } - private string BuildContextName(IEnumerable stack, string attributeName) { - return String.Join("/", stack.Reverse().Skip(1).Select(x => x.Name)) + "/" + attributeName; + private string BuildContextName(IEnumerable stack, string nodeName) { + return String.Format("{0}/{1}", String.Join("/", stack.Reverse().Skip(1).Select(x => x.Name)), nodeName); } } } \ No newline at end of file From 83f5b78919a0f5389d80a6df5d261c6ab620ce08 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 19 Jul 2014 14:43:33 -0700 Subject: [PATCH 088/116] #180: Implementing diff view between saved drafts. --- .../Content/ContentAuditTrailEventShapes.cs | 25 +++++++++++++++---- .../Providers/Content/GlobalContentHandler.cs | 25 ++++++++++++++++--- ...uditTrailEvent-Content.SummaryAdmin.cshtml | 4 +-- .../Views/AuditTrailEvent-Content.cshtml | 15 ++++++----- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs index 00e56bb67..ce2d9659a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Xml.Linq; using Orchard.AuditTrail.Helpers; using Orchard.AuditTrail.Models; using Orchard.ContentManagement; @@ -26,13 +28,12 @@ namespace Orchard.AuditTrail.Providers.Content { var eventData = (IDictionary)context.Shape.EventData; var contentItemId = eventData.Get("ContentId"); var previousContentItemVersionId = eventData.Get("PreviousVersionId"); + var previousVersionXml = GetXml(eventData, "PreviousVersionXml"); + var diffGram = GetXml(eventData, "DiffGram"); var contentItem = _contentManager.Value.Get(contentItemId, VersionOptions.Latest); var previousVersion = previousContentItemVersionId > 0 ? _contentManager.Value.Get(contentItemId, VersionOptions.VersionRecord(previousContentItemVersionId)) : default(ContentItem); - if (previousVersion != null) { - var previousVersionXml = _contentManager.Value.Export(previousVersion); - var currentVersionXml = _contentManager.Value.Export(contentItem); - var diffGram = _analyzer.GenerateDiffGram(previousVersionXml, currentVersionXml); + if (diffGram != null) { var diffNodes = _analyzer.Analyze(previousVersionXml, diffGram).ToArray(); context.Shape.DiffNodes = diffNodes; } @@ -41,5 +42,19 @@ namespace Orchard.AuditTrail.Providers.Content { context.Shape.PreviousVersion = previousVersion; }); } + + private static XElement GetXml(IDictionary eventData, string key) { + var data = eventData.Get(key); + + if (String.IsNullOrWhiteSpace(data)) + return null; + + try { + return XElement.Parse(data); + } + catch (Exception) { + return null; + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index bac779ea0..41873a57d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Xml.Linq; using Orchard.AuditTrail.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -11,19 +12,31 @@ namespace Orchard.AuditTrail.Providers.Content { private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; private readonly IContentManager _contentManager; + private XElement _previousVersionXml; + private readonly IDiffGramAnalyzer _analyzer; - public GlobalContentHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca, IContentManager contentManager) { + public GlobalContentHandler(IAuditTrailManager auditTrailManager, IWorkContextAccessor wca, IContentManager contentManager, IDiffGramAnalyzer analyzer) { _auditTrailManager = auditTrailManager; _wca = wca; _contentManager = contentManager; + _analyzer = analyzer; } protected override void Created(CreateContentContext context) { RecordAuditTrailEvent(ContentAuditTrailEventProvider.Created, context.ContentItem); } + protected override void Updating(UpdateContentContext context) { + var contentItem = context.ContentItem; + _previousVersionXml = _contentManager.Export(contentItem); + } + protected override void Updated(UpdateContentContext context) { - RecordAuditTrailEvent(ContentAuditTrailEventProvider.Saved, context.ContentItem); + var contentItem = context.ContentItem; + var newVersionXml = _contentManager.Export(contentItem); + var diffGram = _analyzer.GenerateDiffGram(_previousVersionXml, newVersionXml); + + RecordAuditTrailEvent(ContentAuditTrailEventProvider.Saved, context.ContentItem, diffGram: diffGram, previousVersionXml: _previousVersionXml); } protected override void Published(PublishContentContext context) { @@ -39,7 +52,7 @@ namespace Orchard.AuditTrail.Providers.Content { RecordAuditTrailEvent(ContentAuditTrailEventProvider.Removed, context.ContentItem); } - private void RecordAuditTrailEvent(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null) { + private void RecordAuditTrailEvent(string eventName, IContent content, ContentItemVersionRecord previousContentItemVersion = null, XElement diffGram = null, XElement previousVersionXml = null) { var blackList = new[] {"Site"}; if (blackList.Contains(content.ContentItem.ContentType)) @@ -56,6 +69,7 @@ namespace Orchard.AuditTrail.Providers.Content { {"ContentIdentity", _contentManager.GetItemMetadata(content).Identity.ToString()}, {"VersionId", content.ContentItem.VersionRecord.Id}, {"VersionNumber", content.ContentItem.VersionRecord.Number}, + {"Published", content.ContentItem.VersionRecord.Published}, {"Title", title} }; @@ -64,6 +78,11 @@ namespace Orchard.AuditTrail.Providers.Content { eventData["PreviousVersionNumber"] = previousContentItemVersion.Number; } + if (diffGram != null && previousVersionXml != null) { + eventData["PreviousVersionXml"] = previousVersionXml.ToString(SaveOptions.DisableFormatting); + eventData["DiffGram"] = diffGram.ToString(SaveOptions.DisableFormatting); + } + _auditTrailManager.CreateRecord( eventName, _wca.GetContext().CurrentUser, diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index a3427afb5..99112ae7a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -1,13 +1,13 @@ @using Orchard.AuditTrail.Helpers @{ var eventData = (IDictionary) Model.EventData; - var title = eventData.Get("Title"); var contentItemId = eventData.Get("ContentId"); var contentItemVersionNumber = eventData.Get("VersionNumber"); + var isPublished = eventData.Get("Published"); }
@T("Version {0}", contentItemVersionNumber) @T(" - ") - @T("View") + @T("View")
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 54a1ac76f..3fd290cf2 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -4,10 +4,13 @@ @{ var record = (AuditTrailEventRecord)Model.Record; var contentItem = (ContentItem)Model.ContentItem; - var previousVersion = (ContentItem)Model.PreviousVersion; - var diffNodes = (IEnumerable)Model.DiffNodes; + var diffNodes = (IList)Model.DiffNodes; +} +@functions { + string FriendlyEmptyString(string value) { + return String.IsNullOrWhiteSpace(value) ? T("").Text : value; + } } -
- @if (previousVersion != null) { + @if (diffNodes != null) { @@ -41,8 +44,8 @@ - - + + } } From a606a7d3d8c8c8792f826e7b899a1963e5e3e866 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 20 Jul 2014 00:04:28 +0200 Subject: [PATCH 089/116] #188: Added missing summary views for role events, and improved wording of existing ones. --- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 7 +++++-- .../Providers/Roles/RoleEventHandler.cs | 1 - ...ated.cshtml => AuditTrailEvent-Role-Created.cshtml} | 2 +- .../Views/AuditTrailEvent-Role-PermissionAdded.cshtml | 2 +- .../AuditTrailEvent-Role-PermissionRemoved.cshtml | 2 +- .../Views/AuditTrailEvent-Role-Removed.cshtml | 9 +++++++++ ...amed.cshtml => AuditTrailEvent-Role-Renamed.cshtml} | 2 +- .../Views/AuditTrailEvent-Role-UserAdded.cshtml | 10 ++++++++++ .../Views/AuditTrailEvent-Role-UserRemoved.cshtml | 10 ++++++++++ 9 files changed, 38 insertions(+), 7 deletions(-) rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/{AuditTrailEvent-Role-RoleCreated.cshtml => AuditTrailEvent-Role-Created.cshtml} (78%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml rename src/Orchard.Web/Modules/Orchard.AuditTrail/Views/{AuditTrailEvent-Role-RoleRenamed.cshtml => AuditTrailEvent-Role-Renamed.cshtml} (73%) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index f3b8d567a..3031cbf75 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -112,8 +112,8 @@ - - + + @@ -136,6 +136,9 @@ + + + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs index 49d040998..eb32cbe05 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs @@ -57,7 +57,6 @@ namespace Orchard.AuditTrail.Providers.Roles { RecordAuditTrailEvent(eventName, roleName, properties: null, eventData: eventData); } - private void RecordAuditTrailEvent(string eventName, string roleName, IUser user) { var properties = new Dictionary { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml similarity index 78% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml index 29e31861f..f2abda990 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleCreated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml @@ -5,5 +5,5 @@ }
- @T("Created {0} role.", roleName) + @T("Created the role {0}.", roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml index 6d9b76ecc..acb13d1c4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml @@ -6,5 +6,5 @@ }
- @T("Added the {0} permission to the {1} role.", permissionName, roleName) + @T("Added the permission {0} to the role {1}.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml index ffbc0bc40..bf43ccd8e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the {0} permission from the {1} role.", permissionName, roleName) + @T("Removed the permission {0} from the role {1}.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml new file mode 100644 index 000000000..b3f07fd6d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml @@ -0,0 +1,9 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); +} + +
+ @T("Removed the role {0}.", roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml similarity index 73% rename from src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml rename to src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml index 769eabd6f..6f9802335 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-RoleRenamed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml @@ -6,5 +6,5 @@ }
- @T("Renamed {0} to {1}.", previousRoleName, newRoleName) + @T("Renamed the role {0} to {1}.", previousRoleName, newRoleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml new file mode 100644 index 000000000..182c49f47 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var roleName = eventData.Get("RoleName"); + var userName = eventData.Get("UserName"); +} + +
+ @T("Added the user {0} to the role {1}.", userName, roleName) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml new file mode 100644 index 000000000..cc5004b83 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml @@ -0,0 +1,10 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary)Model.EventData; + var roleName = eventData.Get("RoleName"); + var userName = eventData.Get("UserName"); +} + +
+ @T("Removed the user {0} from the role {1}.", userName, roleName) +
\ No newline at end of file From 3ac23d4b3209c94cf5bcb34f74350ef3a069834e Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 20 Jul 2014 01:30:46 +0200 Subject: [PATCH 090/116] Unified wording of event summaries. Added missing permission names to role events. --- .../Providers/Roles/RoleEventHandler.cs | 13 +++++++++++-- .../AuditTrailEvent-ContentPart-Created.cshtml | 2 +- .../AuditTrailEvent-ContentPart-FieldAdded.cshtml | 2 +- .../AuditTrailEvent-ContentPart-FieldRemoved.cshtml | 2 +- ...ailEvent-ContentPart-FieldSettingsUpdated.cshtml | 2 +- ...tentPart-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...railEvent-ContentPart-PartSettingsUpdated.cshtml | 2 +- .../AuditTrailEvent-ContentPart-Removed.cshtml | 2 +- .../AuditTrailEvent-ContentType-Created.cshtml | 2 +- ...entType-FieldSettingsUpdated.SummaryAdmin.cshtml | 4 ++-- ...ailEvent-ContentType-FieldSettingsUpdated.cshtml | 4 ++-- .../AuditTrailEvent-ContentType-PartAdded.cshtml | 2 +- .../AuditTrailEvent-ContentType-PartRemoved.cshtml | 2 +- ...tentType-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...railEvent-ContentType-PartSettingsUpdated.cshtml | 2 +- .../AuditTrailEvent-ContentType-Removed.cshtml | 2 +- ...lEvent-ContentType-TypeDisplayNameUpdated.cshtml | 2 +- ...tentType-TypeSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...railEvent-ContentType-TypeSettingsUpdated.cshtml | 2 +- .../Views/AuditTrailEvent-Role-Created.cshtml | 2 +- .../AuditTrailEvent-Role-PermissionAdded.cshtml | 2 +- .../AuditTrailEvent-Role-PermissionRemoved.cshtml | 2 +- .../Views/AuditTrailEvent-Role-Removed.cshtml | 2 +- .../Views/AuditTrailEvent-Role-Renamed.cshtml | 2 +- .../Views/AuditTrailEvent-Role-UserAdded.cshtml | 2 +- .../Views/AuditTrailEvent-Role-UserRemoved.cshtml | 2 +- .../Views/AuditTrailEvent-User-LoginFailed..cshtml | 2 +- .../Views/AuditTrailEvent-User.cshtml | 2 +- 28 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs index eb32cbe05..afd44909b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Roles/RoleEventHandler.cs @@ -34,11 +34,11 @@ namespace Orchard.AuditTrail.Providers.Roles { } public void PermissionAdded(PermissionAddedContext context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionAdded, context.Role.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionAdded, context.Role.Name, context.Permission.Name); } public void PermissionRemoved(PermissionRemovedContext context) { - RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionRemoved, context.Role.Name); + RecordAuditTrailEvent(RoleAuditTrailEventProvider.PermissionRemoved, context.Role.Name, context.Permission.Name); } public void UserAdded(UserAddedContext context) { @@ -57,6 +57,15 @@ namespace Orchard.AuditTrail.Providers.Roles { RecordAuditTrailEvent(eventName, roleName, properties: null, eventData: eventData); } + private void RecordAuditTrailEvent(string eventName, string roleName, string permissionName) { + var eventData = new Dictionary { + {"RoleName", roleName}, + {"PermissionName", permissionName} + }; + + RecordAuditTrailEvent(eventName, roleName, properties: null, eventData: eventData); + } + private void RecordAuditTrailEvent(string eventName, string roleName, IUser user) { var properties = new Dictionary { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml index dedd7c64d..551ba5fa5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml @@ -5,5 +5,5 @@ }
- @T("Created the {0} content part.", contentPartName) + @T("The content part {0} was created.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml index c9bb76bed..f0171e155 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml @@ -8,5 +8,5 @@ }
- @T("Added the {0} content field of type {1} to the {2} content part.", contentFieldName, contentFieldTypeName, contentPartName) + @T("The content field {0} of type {1} was added to the content part {2}.", contentFieldName, contentFieldTypeName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml index eed00a730..f439d70da 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the {0} content field from the {1} content part.", contentFieldName, contentPartName) + @T("The content field {0} was removed from the content part {1}.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml index 04fe1f0a8..0f55b9fb4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml @@ -8,5 +8,5 @@ }
- @T("The {0} content field of the {1} content part was renamed from {2} to {3}.", contentFieldName, contentPartName, oldDisplayName, newDisplayName) + @T("The content field {0} of the content part {1} was renamed from {2} to {3}.", contentFieldName, contentPartName, oldDisplayName, newDisplayName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml index 8ba2ea59e..41e1cc45f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -14,7 +14,7 @@ var diff = (DiffDictionary)Model.Diff; }
-
@T("Settings for {0} were updated:", contentPartName)
+ @T("Settings for the content part {0} were changed:", contentPartName)
    @foreach (var setting in diff) {
  • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index b6935237e..0baa90249 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -14,7 +14,7 @@ var diff = (DiffDictionary)Model.Diff; }
    -

    @T("Settings for {0} were updated:", contentPartName)

    + @T("Settings for the content part {0} were changed:", contentPartName)
@T(node.Type.ToString()) @node.Context@node.Previous@node.Current@FriendlyEmptyString(node.Previous)@FriendlyEmptyString(node.Current)
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml index 167daf607..c1ed2e156 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml @@ -5,5 +5,5 @@ }
- @T("Removed the {0} content part.", contentPartName) + @T("The content part {0} was removed.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml index 80d4a2ca0..4e60d28d7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml @@ -6,5 +6,5 @@ }
- @T("Created the {0} content type.", contentTypeName) + @T("The content type {0} was created.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml index 7d6b42398..d9758d01b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -15,10 +15,10 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for {0} attached the {1} content type were updated:" : "Settings for {0} attached to {1} of the {2} content type were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the {1} content type were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; }
-
@T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
+ @T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
    @foreach (var setting in diff) {
  • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml index 27bce0b92..5e072adaa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml @@ -15,10 +15,10 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for {0} attached the {1} content type were updated:" : "Settings for {0} attached to {1} of the {2} content type were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the {1} content type were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; }
    -

    @T(captionTemplate, contentFieldName, contentPartName, contentTypeName)

    + @T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml index 8bace8ba5..07c5e7872 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml @@ -6,5 +6,5 @@ }
- @T("Added the {0} content part to the {1} content type.", contentPartName, contentTypeName) + @T("The content part {0} was added to the content type {1}.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml index 3a0697226..45a087b5a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the {0} content part from the {1} content type.", contentPartName, contentTypeName) + @T("The content part {0} was removed from the content type {1}.", contentPartName, contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml index 52360ad99..32c15ab6f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -15,7 +15,7 @@ var diff = (DiffDictionary)Model.Diff; }
-
@T("Settings for {0} attached to the {1} content type were updated:", contentPartName, contentTypeName)
+ @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName)
    @foreach (var setting in diff) {
  • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index 5cbc92ef0..9e711256a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -15,7 +15,7 @@ var diff = (DiffDictionary)Model.Diff; }
    -

    @T("Settings for {0} attached to the {1} content type were updated:", contentPartName, contentTypeName)

    + @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName)
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml index bdbbc7083..c786b2f35 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the {0} content type.", contentTypeName) + @T("The content type {0} was removed.", contentTypeName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml index 06c100842..4905d2a8f 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml @@ -7,5 +7,5 @@ }
- @T("The display name for the {0} content type was changed from {1} to {2}.", contentTypeName, oldDisplayName, newDisplayName) + @T("The display name for the content type {0} was changed from {1} to {2}.", contentTypeName, oldDisplayName, newDisplayName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index 0bcef5e06..130c67f26 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -15,7 +15,7 @@ }
- @T("The following {0} settings were changed:", contentTypeName)
+ @T("Settings for the content type {0} were changed:", contentTypeName)
    @foreach (var setting in diff) {
  • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index f773fb1fc..cee4efc95 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -14,7 +14,7 @@ var diff = (DiffDictionary) Model.Diff; }
    -

    @T("The following {0} settings were changed", contentTypeName)

    + @T("Settings for the content type {0} were changed:", contentTypeName)
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml index f2abda990..5aa6f09c7 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml @@ -5,5 +5,5 @@ }
- @T("Created the role {0}.", roleName) + @T("The role {0} was created.", roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml index acb13d1c4..4cfe482d0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml @@ -6,5 +6,5 @@ }
- @T("Added the permission {0} to the role {1}.", permissionName, roleName) + @T("The permission {0} was added to the role {1}.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml index bf43ccd8e..7d79e5b9b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the permission {0} from the role {1}.", permissionName, roleName) + @T("The permission {0} was removed from the role {1}.", permissionName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml index b3f07fd6d..301738a94 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml @@ -5,5 +5,5 @@ }
- @T("Removed the role {0}.", roleName) + @T("The role {0} was removed.", roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml index 6f9802335..7004391cd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml @@ -6,5 +6,5 @@ }
- @T("Renamed the role {0} to {1}.", previousRoleName, newRoleName) + @T("The role {0} was renamed to {1}.", previousRoleName, newRoleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml index 182c49f47..c826ff9ba 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml @@ -6,5 +6,5 @@ }
- @T("Added the user {0} to the role {1}.", userName, roleName) + @T("The user {0} was added to the role {1}.", userName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml index cc5004b83..8f035bb55 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml @@ -6,5 +6,5 @@ }
- @T("Removed the user {0} from the role {1}.", userName, roleName) + @T("The user {0} was removed from the role {1}.", userName, roleName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml index d59b373b9..e9ae640f1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml @@ -5,5 +5,5 @@ }
- @T("Attempted user name: {0}", userName) + @T("Attempted user name: {0}", userName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml index 87e06a634..a33fecea8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml @@ -5,5 +5,5 @@ }
- @T("User: {0}", userName) + @T("User name: {0}", userName)
\ No newline at end of file From 104c051783e82b8854db059021e1c2822858385a Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 20 Jul 2014 15:27:00 +0200 Subject: [PATCH 091/116] Removed duplicated ToFriendlyEmpty() methods and introduced an equivalent extension method. Changed to [Empty] to avoid HTML encoding problems. --- .../Orchard.AuditTrail/Helpers/StringExtensions.cs | 5 +++++ ...t-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml | 7 +------ ...uditTrailEvent-ContentPart-PartSettingsUpdated.cshtml | 9 ++------- ...-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml | 7 +------ ...ditTrailEvent-ContentType-FieldSettingsUpdated.cshtml | 9 ++------- ...t-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml | 7 +------ ...uditTrailEvent-ContentType-PartSettingsUpdated.cshtml | 9 ++------- ...t-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml | 8 +------- ...uditTrailEvent-ContentType-TypeSettingsUpdated.cshtml | 9 ++------- 9 files changed, 17 insertions(+), 53 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs index 224c17986..644e06917 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/StringExtensions.cs @@ -1,4 +1,5 @@ using System; +using Orchard.Localization; namespace Orchard.AuditTrail.Helpers { public static class StringExtensions { @@ -12,5 +13,9 @@ namespace Orchard.AuditTrail.Helpers { return i; } + + public static string OrIfEmpty(this string value, LocalizedString emptyString) { + return String.IsNullOrWhiteSpace(value) ? emptyString.Text : value; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml index 41e1cc45f..6523715f5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary)Model.EventData; var contentPartName = eventData.Get("ContentPartName"); @@ -18,7 +13,7 @@
    @foreach (var setting in diff) {
  • - @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) + @T("{0} was changed from {1} to {2}.", setting.Key, setting.Value.OldValue.OrIfEmpty(T("[Empty]")), setting.Value.NewValue.OrIfEmpty(T("[Empty]")))
  • }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index 0baa90249..ecea3c786 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary)Model.EventData; var contentPartName = eventData.Get("ContentPartName"); @@ -27,8 +22,8 @@ @foreach (var setting in diff) {
- - + + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml index d9758d01b..b642efdc0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); @@ -22,7 +17,7 @@
    @foreach (var setting in diff) {
  • - @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) + @T("{0} was changed from {1} to {2}.", setting.Key, setting.Value.OldValue.OrIfEmpty(T("[Empty]")), setting.Value.NewValue.OrIfEmpty(T("[Empty]")))
  • }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml index 5e072adaa..bfc141dcc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? T("").Text : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); @@ -31,8 +26,8 @@ @foreach (var setting in diff) {
- - + + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml index 32c15ab6f..aa899735d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); @@ -19,7 +14,7 @@
    @foreach (var setting in diff) {
  • - @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) + @T("{0} was changed from {1} to {2}.", setting.Key, setting.Value.OldValue.OrIfEmpty(T("[Empty]")), setting.Value.NewValue.OrIfEmpty(T("[Empty]")))
  • }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index 9e711256a..187fd1d31 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); @@ -28,8 +23,8 @@ @foreach (var setting in diff) {
- - + + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index 130c67f26..cfa7d6fff 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -3,23 +3,17 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? Html.Encode(T("").Text) : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); var diff = (DiffDictionary) Model.Diff; } -
@T("Settings for the content type {0} were changed:", contentTypeName)
    @foreach (var setting in diff) {
  • - @T("{0} was changed from {1} to {2}.", setting.Key, ToFriendlyEmpty(setting.Value.OldValue), ToFriendlyEmpty(setting.Value.NewValue)) + @T("{0} was changed from {1} to {2}.", setting.Key, setting.Value.OldValue.OrIfEmpty(T("[Empty]")), setting.Value.NewValue.OrIfEmpty(T("[Empty]")))
  • }
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index cee4efc95..dbccb3907 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -3,11 +3,6 @@ @{ Style.Include("audittrail-contenttype-event.css"); } -@functions { - static string ToFriendlyEmpty(string value) { - return String.IsNullOrWhiteSpace(value) ? "" : value; - } -} @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); @@ -27,8 +22,8 @@ @foreach (var setting in diff) {
- - + + } From 15bdcadd4f516f5e294e5f98ba025ca915525865 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 20 Jul 2014 16:44:49 +0200 Subject: [PATCH 092/116] #194: Implemented the missing ContentPart.DescriptionChanged event. --- .../Orchard.AuditTrail.csproj | 1 + .../GlobalContentDefinitionEditorEvents.cs | 26 ++++++++++++++++--- ...vent-ContentPart-DescriptionChanged.cshtml | 11 ++++++++ ...-ContentType-TypeDisplayNameUpdated.cshtml | 2 +- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 3031cbf75..41526d5e3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -139,6 +139,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs index c790fb513..cacd0e0bc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/ContentDefinition/GlobalContentDefinitionEditorEvents.cs @@ -15,6 +15,7 @@ using Orchard.Environment.Extensions; namespace Orchard.AuditTrail.Providers.ContentDefinition { [OrchardFeature("Orchard.AuditTrail.ContentDefinition")] public class GlobalContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase { + private const string _contentPartSettingsDescriptionName = "ContentPartSettings.Description"; private readonly IAuditTrailManager _auditTrailManager; private readonly IWorkContextAccessor _wca; private readonly IContentDefinitionService _contentDefinitionService; @@ -118,13 +119,30 @@ namespace Orchard.AuditTrail.Providers.ContentDefinition { public override void PartEditorUpdated(ContentPartDefinitionBuilder builder) { var contentPartDefinition = builder.Build(); - var newSettings = contentPartDefinition.Settings; + var newPartSettings = contentPartDefinition.Settings; - if (!AreEqual(newSettings, _oldPartSettings)) { + if (newPartSettings.ContainsKey(_contentPartSettingsDescriptionName)) { + var oldDescription = _oldPartSettings.Get(_contentPartSettingsDescriptionName); + var newDescription = newPartSettings.Get(_contentPartSettingsDescriptionName); + if (oldDescription != newDescription) { + var eventData = new Dictionary { + {"ContentPartName", builder.Name}, + {"OldDescription", oldDescription}, + {"NewDescription", newDescription} + }; + RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.DescriptionChanged, eventData, builder.Name); + } + } + + // Description change should not be re-recorded as general settings change. + var remainingOldPartSettings = new SettingsDictionary(_oldPartSettings.Where(item => item.Key != _contentPartSettingsDescriptionName).ToDictionary(item => item.Key, item => item.Value)); + var remainingNewPartSettings = new SettingsDictionary(newPartSettings.Where(item => item.Key != _contentPartSettingsDescriptionName).ToDictionary(item => item.Key, item => item.Value)); + + if (!AreEqual(remainingNewPartSettings, remainingOldPartSettings)) { var eventData = new Dictionary { {"ContentPartName", builder.Name}, - {"OldSettings", ToXml(_oldPartSettings)}, - {"NewSettings", ToXml(newSettings)} + {"OldSettings", ToXml(remainingOldPartSettings)}, + {"NewSettings", ToXml(remainingNewPartSettings)} }; RecordContentPartAuditTrail(ContentPartAuditTrailEventProvider.PartSettingsUpdated, eventData, builder.Name); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml new file mode 100644 index 000000000..491d67dc7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml @@ -0,0 +1,11 @@ +@using Orchard.AuditTrail.Helpers +@{ + var eventData = (IDictionary) Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var oldDescription = eventData.Get("OldDescription"); + var newDescription = eventData.Get("NewDescription"); +} + +
+ @T("The description of content part {0} was changed from {1} to {2}.", contentPartName, oldDescription.OrIfEmpty(T("[Empty]")), newDescription.OrIfEmpty(T("[Empty]"))) +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml index 4905d2a8f..cb1a3dbb8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml @@ -7,5 +7,5 @@ }
- @T("The display name for the content type {0} was changed from {1} to {2}.", contentTypeName, oldDisplayName, newDisplayName) + @T("The display name for the content type {0} was changed from {1} to {2}.", contentTypeName, oldDisplayName.OrIfEmpty(T("[Empty]")), newDisplayName.OrIfEmpty(T("[Empty]")))
\ No newline at end of file From 1fd8cd2580f6b2ef97fb45afa0df7545c99f6c77 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Sun, 20 Jul 2014 17:59:01 +0200 Subject: [PATCH 093/116] #191: Fixed display of content part field settings change event. Cleaned up and refactored audit trail event summary views and corresponding CSS. --- .../Orchard.AuditTrail.csproj | 3 +- .../audittrail-contentdefinition-event.css | 22 ++++++++++++++ .../Styles/audittrail-contenttype-event.css | 26 ---------------- .../Styles/audittrail-settings-event.css | 4 +-- ...Settings-EventsChanged.SummaryAdmin.cshtml | 2 +- ...nt-AuditTrailSettings-EventsChanged.cshtml | 2 +- ...ailSettings-TrimmingSettingsChanged.cshtml | 3 +- ...uditTrailEvent-Content.SummaryAdmin.cshtml | 3 +- .../Views/AuditTrailEvent-Content.cshtml | 5 ++-- ...AuditTrailEvent-ContentPart-Created.cshtml | 3 +- ...vent-ContentPart-DescriptionChanged.cshtml | 3 +- ...itTrailEvent-ContentPart-FieldAdded.cshtml | 3 +- ...TrailEvent-ContentPart-FieldRemoved.cshtml | 3 +- ...t-FieldSettingsUpdated.SummaryAdmin.cshtml | 23 ++++++++++++++ ...nt-ContentPart-FieldSettingsUpdated.cshtml | 30 ++++++++++++++++--- ...rt-PartSettingsUpdated.SummaryAdmin.cshtml | 4 +-- ...ent-ContentPart-PartSettingsUpdated.cshtml | 4 +-- ...AuditTrailEvent-ContentPart-Removed.cshtml | 3 +- ...AuditTrailEvent-ContentType-Created.cshtml | 3 +- ...e-FieldSettingsUpdated.SummaryAdmin.cshtml | 6 ++-- ...nt-ContentType-FieldSettingsUpdated.cshtml | 6 ++-- ...ditTrailEvent-ContentType-PartAdded.cshtml | 3 +- ...tTrailEvent-ContentType-PartRemoved.cshtml | 3 +- ...pe-PartSettingsUpdated.SummaryAdmin.cshtml | 4 +-- ...ent-ContentType-PartSettingsUpdated.cshtml | 4 +-- ...AuditTrailEvent-ContentType-Removed.cshtml | 3 +- ...-ContentType-TypeDisplayNameUpdated.cshtml | 3 +- ...pe-TypeSettingsUpdated.SummaryAdmin.cshtml | 4 +-- ...ent-ContentType-TypeSettingsUpdated.cshtml | 4 +-- .../Views/AuditTrailEvent-Role-Created.cshtml | 3 +- ...uditTrailEvent-Role-PermissionAdded.cshtml | 3 +- ...itTrailEvent-Role-PermissionRemoved.cshtml | 3 +- .../Views/AuditTrailEvent-Role-Removed.cshtml | 3 +- .../Views/AuditTrailEvent-Role-Renamed.cshtml | 3 +- .../AuditTrailEvent-Role-UserAdded.cshtml | 3 +- .../AuditTrailEvent-Role-UserRemoved.cshtml | 3 +- .../AuditTrailEvent-User-LoginFailed..cshtml | 3 +- .../Views/AuditTrailEvent-User.cshtml | 3 +- 38 files changed, 118 insertions(+), 98 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contentdefinition-event.css delete mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 41526d5e3..b38eef750 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -84,7 +84,7 @@ - + @@ -140,6 +140,7 @@ +
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contentdefinition-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contentdefinition-event.css new file mode 100644 index 000000000..cd0d719ff --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contentdefinition-event.css @@ -0,0 +1,22 @@ +section.audittrail-contenttype-eventsummary table.items, +section.audittrail-contentpart-eventsummary table.items { + width: auto; + min-width: 600px; + margin: 0; +} + +section.audittrail-contenttype-eventsummary table.items thead th, +section.audittrail-contentpart-eventsummary table.items thead th { + font-weight: bold; +} + +section.audittrail-contenttype-eventsummary ul, +section.audittrail-contentpart-eventsummary ul { + list-style-type: square; + margin-left: 1.5em; +} + +section.audittrail-contenttype-eventsummary ul li, +section.audittrail-contentpart-eventsummary ul li { + padding-left: 0.5em; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css deleted file mode 100644 index 819cdf65d..000000000 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-contenttype-event.css +++ /dev/null @@ -1,26 +0,0 @@ -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; -} - -section.audittrail-contenttype-event ul { - list-style-type: square; - margin-left: 1.5em; -} - -section.audittrail-contenttype-event ul li { - padding-left: 0.5em; -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css index 8de6a3828..2682884b9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-settings-event.css @@ -1,9 +1,9 @@ -section.audittrail-settings-event table.audittrail-events { +section.audittrail-settings-eventsummary table.audittrail-events { width: auto; margin: 0; } -section.audittrail-settings-event tbody.audittrail-category tr th { +section.audittrail-settings-eventsummary tbody.audittrail-category tr th { background-color: #ebebeb; font-size: 1.1em; font-weight: bold; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml index 442730424..bc8f0f3fe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.SummaryAdmin.cshtml @@ -3,6 +3,6 @@ var diff = (IList)Model.Diff; var descriptions = String.Join("
", diff.Select(x => T("The {0} event in category {1} was {2}.", x.Descriptor.Name, x.Descriptor.CategoryDescriptor.Name, x.Setting.IsEnabled ? "enabled" : "disabled").Text)); } -
+
@Html.Raw(descriptions)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml index 8d40801fe..33ba066d4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-EventsChanged.cshtml @@ -6,7 +6,7 @@ var diff = (IList)Model.Diff; var groups = diff.GroupBy(x => x.Descriptor.CategoryDescriptor.Name).OrderBy(x => x.Key.Text); } -
+
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)@setting.Value.OldValue.OrIfEmpty(T("[Empty]"))@setting.Value.NewValue.OrIfEmpty(T("[Empty]"))
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)@setting.Value.OldValue.OrIfEmpty(T("[Empty]"))@setting.Value.NewValue.OrIfEmpty(T("[Empty]"))
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)@setting.Value.OldValue.OrIfEmpty(T("[Empty]"))@setting.Value.NewValue.OrIfEmpty(T("[Empty]"))
@setting.Key@ToFriendlyEmpty(setting.Value.OldValue)@ToFriendlyEmpty(setting.Value.NewValue)@setting.Value.OldValue.OrIfEmpty(T("[Empty]"))@setting.Value.NewValue.OrIfEmpty(T("[Empty]"))
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml index 84a305e65..d9edf8dd0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-AuditTrailSettings-TrimmingSettingsChanged.cshtml @@ -6,8 +6,7 @@ var oldMinimumRunInterval = eventData.Get("OldMinimumRunInterval"); var newMinimumRunInterval = eventData.Get("NewMinimumRunInterval"); } - -
+
@if (newRetentionPeriod != oldRetentionPeriod) {
@T("The trimming retention period was changed from {0} to {1}.", T.Plural("1 day", "{0} days", oldRetentionPeriod), T.Plural("1 day", "{0} days", newRetentionPeriod))
} diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index 99112ae7a..0578282b4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -5,8 +5,7 @@ var contentItemVersionNumber = eventData.Get("VersionNumber"); var isPublished = eventData.Get("Published"); } - -
+
@T("Version {0}", contentItemVersionNumber) @T(" - ") @T("View") diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 3fd290cf2..1511c5238 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -11,7 +11,7 @@ return String.IsNullOrWhiteSpace(value) ? T("").Text : value; } } -
diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml index 551ba5fa5..e237fdb3e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Created.cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var contentPartName = eventData.Get("ContentPartName"); } - -
+
@T("The content part {0} was created.", contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml index 491d67dc7..ac927bf34 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-DescriptionChanged.cshtml @@ -5,7 +5,6 @@ var oldDescription = eventData.Get("OldDescription"); var newDescription = eventData.Get("NewDescription"); } - -
+
@T("The description of content part {0} was changed from {1} to {2}.", contentPartName, oldDescription.OrIfEmpty(T("[Empty]")), newDescription.OrIfEmpty(T("[Empty]")))
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml index f0171e155..11d856938 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldAdded.cshtml @@ -6,7 +6,6 @@ var contentFieldTypeName = eventData.Get("ContentFieldTypeName"); var contentDisplayName = eventData.Get("ContentDisplayName"); } - -
+
@T("The content field {0} of type {1} was added to the content part {2}.", contentFieldName, contentFieldTypeName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml index f439d70da..1fd93ccf5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldRemoved.cshtml @@ -4,7 +4,6 @@ var contentPartName = eventData.Get("ContentPartName"); var contentFieldName = eventData.Get("ContentFieldName"); } - -
+
@T("The content field {0} was removed from the content part {1}.", contentFieldName, contentPartName)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml new file mode 100644 index 000000000..2378db260 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -0,0 +1,23 @@ +@using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models +@{ + Style.Include("audittrail-contentdefinition-event.css"); +} +@{ + var eventData = (IDictionary)Model.EventData; + var contentPartName = eventData.Get("ContentPartName"); + var contentFieldName = eventData.Get("ContentFieldName"); + var oldDisplayName = (string)Model.OldDisplayName; + var newDisplayName = (string)Model.NewDisplayName; + var diff = (DiffDictionary)Model.Diff; +} +
+ @T("Settings for the field {0} attached to the {1} content type were updated:", contentFieldName, contentPartName) +
    + @foreach (var setting in diff) { +
  • + @T("{0} was changed from {1} to {2}.", setting.Key, setting.Value.OldValue.OrIfEmpty(T("[Empty]")), setting.Value.NewValue.OrIfEmpty(T("[Empty]"))) +
  • + } +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml index 0f55b9fb4..392517de1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-FieldSettingsUpdated.cshtml @@ -1,12 +1,34 @@ @using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models @{ - var eventData = (IDictionary) Model.EventData; + Style.Include("audittrail-contentdefinition-event.css"); +} +@{ + var eventData = (IDictionary)Model.EventData; var contentPartName = eventData.Get("ContentPartName"); var contentFieldName = eventData.Get("ContentFieldName"); var oldDisplayName = (string)Model.OldDisplayName; var newDisplayName = (string)Model.NewDisplayName; + var diff = (DiffDictionary)Model.Diff; } - -
- @T("The content field {0} of the content part {1} was renamed from {2} to {3}.", contentFieldName, contentPartName, oldDisplayName, newDisplayName) +
+ @T("Settings for the field {0} attached to the {1} content type were updated:", contentFieldName, contentPartName) +
+ + + + + + + + + @foreach (var setting in diff) { + + + + + + } + +
@T("Setting")@T("From")@T("To")
@setting.Key@setting.Value.OldValue.OrIfEmpty(T("[Empty]"))@setting.Value.NewValue.OrIfEmpty(T("[Empty]"))
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml index 6523715f5..fc1c8ff5b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -1,14 +1,14 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary)Model.EventData; var contentPartName = eventData.Get("ContentPartName"); var diff = (DiffDictionary)Model.Diff; } -
+
@T("Settings for the content part {0} were changed:", contentPartName)
    @foreach (var setting in diff) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index ecea3c786..8f549c89a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -1,14 +1,14 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary)Model.EventData; var contentPartName = eventData.Get("ContentPartName"); var diff = (DiffDictionary)Model.Diff; } -
    +
    @T("Settings for the content part {0} were changed:", contentPartName) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml index c1ed2e156..a46fae52b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-Removed.cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var contentPartName = eventData.Get("ContentPartName"); } - -
    +
    @T("The content part {0} was removed.", contentPartName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml index 4e60d28d7..4354b6a7e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml @@ -4,7 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } - -
    +
    @T("The content type {0} was created.", contentTypeName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml index b642efdc0..2056b2a7e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -1,7 +1,7 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; @@ -10,9 +10,9 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the {1} content type were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; } -
    +
    @T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
      @foreach (var setting in diff) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml index bfc141dcc..ecae29265 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml @@ -1,7 +1,7 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; @@ -10,9 +10,9 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the {1} content type were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; } -
      +
      @T(captionTemplate, contentFieldName, contentPartName, contentTypeName)
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml index 07c5e7872..cab906c38 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml @@ -4,7 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); var contentPartName = eventData.Get("ContentPartName"); } - -
    +
    @T("The content part {0} was added to the content type {1}.", contentPartName, contentTypeName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml index 45a087b5a..a92b075d5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml @@ -4,7 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); var contentPartName = eventData.Get("ContentPartName"); } - -
    +
    @T("The content part {0} was removed from the content type {1}.", contentPartName, contentTypeName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml index aa899735d..0b6ba8139 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -1,7 +1,7 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; @@ -9,7 +9,7 @@ var contentPartName = eventData.Get("ContentPartName"); var diff = (DiffDictionary)Model.Diff; } -
    +
    @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName)
      @foreach (var setting in diff) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index 187fd1d31..7105743e1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -1,7 +1,7 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; @@ -9,7 +9,7 @@ var contentPartName = eventData.Get("ContentPartName"); var diff = (DiffDictionary)Model.Diff; } -
      +
      @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName)
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml index c786b2f35..910a1c394 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Removed.cshtml @@ -4,7 +4,6 @@ var contentTypeName = eventData.Get("ContentTypeName"); var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); } - -
    +
    @T("The content type {0} was removed.", contentTypeName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml index cb1a3dbb8..02d942e9a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml @@ -5,7 +5,6 @@ var oldDisplayName = eventData.Get("OldDisplayName"); var newDisplayName = eventData.Get("NewDisplayName"); } - -
    +
    @T("The display name for the content type {0} was changed from {1} to {2}.", contentTypeName, oldDisplayName.OrIfEmpty(T("[Empty]")), newDisplayName.OrIfEmpty(T("[Empty]")))
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index cfa7d6fff..463c37186 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -1,14 +1,14 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); var diff = (DiffDictionary) Model.Diff; } -
    +
    @T("Settings for the content type {0} were changed:", contentTypeName)
      @foreach (var setting in diff) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index dbccb3907..56729adfa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -1,14 +1,14 @@ @using Orchard.AuditTrail.Helpers @using Orchard.AuditTrail.Services.Models @{ - Style.Include("audittrail-contenttype-event.css"); + Style.Include("audittrail-contentdefinition-event.css"); } @{ var eventData = (IDictionary) Model.EventData; var contentTypeName = eventData.Get("ContentTypeName"); var diff = (DiffDictionary) Model.Diff; } -
      +
      @T("Settings for the content type {0} were changed:", contentTypeName)
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml index 5aa6f09c7..4459e63c4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Created.cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var roleName = eventData.Get("RoleName"); } - -
    +
    @T("The role {0} was created.", roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml index 4cfe482d0..5f53b64ee 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionAdded.cshtml @@ -4,7 +4,6 @@ var roleName = eventData.Get("RoleName"); var permissionName = eventData.Get("PermissionName"); } - -
    +
    @T("The permission {0} was added to the role {1}.", permissionName, roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml index 7d79e5b9b..e22a052f1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-PermissionRemoved.cshtml @@ -4,7 +4,6 @@ var roleName = eventData.Get("RoleName"); var permissionName = eventData.Get("PermissionName"); } - -
    +
    @T("The permission {0} was removed from the role {1}.", permissionName, roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml index 301738a94..c796dbbf8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Removed.cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var roleName = eventData.Get("RoleName"); } - -
    +
    @T("The role {0} was removed.", roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml index 7004391cd..557a0d83d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-Renamed.cshtml @@ -4,7 +4,6 @@ var previousRoleName = eventData.Get("PreviousRoleName"); var newRoleName = eventData.Get("NewRoleName"); } - -
    +
    @T("The role {0} was renamed to {1}.", previousRoleName, newRoleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml index c826ff9ba..7d472eb64 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserAdded.cshtml @@ -4,7 +4,6 @@ var roleName = eventData.Get("RoleName"); var userName = eventData.Get("UserName"); } - -
    +
    @T("The user {0} was added to the role {1}.", userName, roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml index 8f035bb55..e9165d306 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Role-UserRemoved.cshtml @@ -4,7 +4,6 @@ var roleName = eventData.Get("RoleName"); var userName = eventData.Get("UserName"); } - -
    +
    @T("The user {0} was removed from the role {1}.", userName, roleName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml index e9ae640f1..aae0a8da0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User-LoginFailed..cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var userName = eventData.Get("UserName"); } - -
    +
    @T("Attempted user name: {0}", userName)
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml index a33fecea8..a37c33c6d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-User.cshtml @@ -3,7 +3,6 @@ var eventData = (IDictionary) Model.EventData; var userName = eventData.Get("UserName"); } - -
    +
    @T("User name: {0}", userName)
    \ No newline at end of file From b66c8adfe33928bad0b18f97967b6e162b4e9903 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sun, 20 Jul 2014 20:19:40 -0700 Subject: [PATCH 094/116] Updating various migrations to use proper Boolean strings and proper JSON. This will lessen the number of content type definition audit trail events generated when a user saves a content type definition without actually making any changes. --- .../Modules/Orchard.Blogs/Migrations.cs | 14 +++++++------- .../Modules/Orchard.CustomForms/Migrations.cs | 6 +++--- .../Modules/Orchard.Lists/Migrations.cs | 6 +++--- .../Modules/Orchard.Pages/Migrations.cs | 10 +++++----- .../Modules/Orchard.Projections/Migrations.cs | 6 +++--- .../Modules/Orchard.Taxonomies/Migrations.cs | 6 +++--- .../Orchard.Taxonomies/Services/TaxonomyService.cs | 6 +++--- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs index 18b5fc85c..293b3bef0 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs @@ -37,9 +37,9 @@ namespace Orchard.Blogs { .WithPart("CommonPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-blog'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-blog\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("MenuPart") .WithPart("AdminMenuPart", p => p.WithSetting("AdminMenuPartTypeSettings.DefaultPosition", "2")) @@ -52,13 +52,13 @@ namespace Orchard.Blogs { cfg => cfg .WithPart("BlogPostPart") .WithPart("CommonPart", p => p - .WithSetting("DateEditorSettings.ShowDateEditor", "true")) + .WithSetting("DateEditorSettings.ShowDateEditor", "True")) .WithPart("PublishLaterPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Blog and Title', Pattern: '{Content.Container.Path}/{Content.Slug}', Description: 'my-blog/my-post'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Blog and Title\",\"Pattern\":\"{Content.Container.Path}/{Content.Slug}\",\"Description\":\"my-blog/my-post\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("BodyPart") .Draftable() diff --git a/src/Orchard.Web/Modules/Orchard.CustomForms/Migrations.cs b/src/Orchard.Web/Modules/Orchard.CustomForms/Migrations.cs index 011ac119a..a09bfa7fe 100644 --- a/src/Orchard.Web/Modules/Orchard.CustomForms/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.CustomForms/Migrations.cs @@ -10,9 +10,9 @@ namespace Orchard.CustomForms { .WithPart("CommonPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-form'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-form\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("MenuPart") .WithPart("CustomFormPart") diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Lists/Migrations.cs index 9af5d5778..54cefe633 100644 --- a/src/Orchard.Web/Modules/Orchard.Lists/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Lists/Migrations.cs @@ -11,9 +11,9 @@ namespace Orchard.Lists { .WithPart("ContainerPart") .WithPart("MenuPart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-list'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-list\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))); return 4; } diff --git a/src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs index 768f0d935..22307acf0 100644 --- a/src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs @@ -8,13 +8,13 @@ namespace Orchard.Pages { ContentDefinitionManager.AlterTypeDefinition("Page", cfg => cfg .WithPart("CommonPart", p => p - .WithSetting("DateEditorSettings.ShowDateEditor", "true")) + .WithSetting("DateEditorSettings.ShowDateEditor", "True")) .WithPart("PublishLaterPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-page'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-page\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("BodyPart") .Creatable()); @@ -23,7 +23,7 @@ namespace Orchard.Pages { } public int UpdateFrom1() { - ContentDefinitionManager.AlterTypeDefinition("Page", cfg => cfg.WithPart("CommonPart", p => p.WithSetting("DateEditorSettings.ShowDateEditor", "true"))); + ContentDefinitionManager.AlterTypeDefinition("Page", cfg => cfg.WithPart("CommonPart", p => p.WithSetting("DateEditorSettings.ShowDateEditor", "True"))); return 2; } } diff --git a/src/Orchard.Web/Modules/Orchard.Projections/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Projections/Migrations.cs index b583372cc..1e14553f3 100644 --- a/src/Orchard.Web/Modules/Orchard.Projections/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Projections/Migrations.cs @@ -188,9 +188,9 @@ namespace Orchard.Projections { .WithPart("CommonPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-projections'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-projections\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("MenuPart") .WithPart("ProjectionPart") diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs index 9ea2514a1..5296f1e84 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs @@ -32,9 +32,9 @@ namespace Orchard.Taxonomies { .WithPart("CommonPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-taxonomy'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Title\",\"Pattern\":\"{Content.Slug}\",\"Description\":\"my-taxonomy\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) ); diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs index d7dd0c8b4..8d75504c1 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs @@ -90,9 +90,9 @@ namespace Orchard.Taxonomies.Services { .WithPart("TermPart") .WithPart("TitlePart") .WithPart("AutoroutePart", builder => builder - .WithSetting("AutorouteSettings.AllowCustomPattern", "true") - .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") - .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Taxonomy and Title', Pattern: '{Content.Container.Path}/{Content.Slug}', Description: 'my-taxonomy/my-term/sub-term'}]") + .WithSetting("AutorouteSettings.AllowCustomPattern", "True") + .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "False") + .WithSetting("AutorouteSettings.PatternDefinitions", "[{\"Name\":\"Taxonomy and Title\",\"Pattern\":\"{Content.Container.Path}/{Content.Slug}\",\"Description\":\"my-taxonomy/my-term/sub-term\"}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0")) .WithPart("CommonPart") .DisplayedAs(taxonomy.Name + " Term") From da4397c1cd25777b6de02c04692c343fe16dc901 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 23 Jul 2014 19:18:16 -0700 Subject: [PATCH 095/116] #180: Updating Save events to not show "view" link. Current drafts shows an "edit" link. --- .../Providers/Content/GlobalContentHandler.cs | 1 + .../Views/AuditTrailEvent-Content.SummaryAdmin.cshtml | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 41873a57d..6244b4e84 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -70,6 +70,7 @@ namespace Orchard.AuditTrail.Providers.Content { {"VersionId", content.ContentItem.VersionRecord.Id}, {"VersionNumber", content.ContentItem.VersionRecord.Number}, {"Published", content.ContentItem.VersionRecord.Published}, + {"Latest", content.ContentItem.VersionRecord.Latest}, {"Title", title} }; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index 0578282b4..7e2e123b4 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -4,9 +4,16 @@ var contentItemId = eventData.Get("ContentId"); var contentItemVersionNumber = eventData.Get("VersionNumber"); var isPublished = eventData.Get("Published"); + var isLatest = eventData.Get("Latest"); }
    @T("Version {0}", contentItemVersionNumber) - @T(" - ") - @T("View") + @if (isPublished) { + @T(" - ") + @T("View") + } + else if (isLatest) { + @T(" - ") + @T("Edit") + }
    \ No newline at end of file From 3ee4712222cf2f9143d248786b0dfde198ee744a Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 23 Jul 2014 22:59:34 -0700 Subject: [PATCH 096/116] #195: Implementing filter model validation and handling invalid from/to date values. --- .../Controllers/AdminController.cs | 22 +++++++++++++++++-- .../Drivers/AuditTrailPartDriver.cs | 10 ++++++--- .../Content/ContentAuditTrailEventProvider.cs | 4 ++-- .../Services/AuditTrailManager.cs | 1 - .../Services/CommonAuditTrailEventHandler.cs | 20 ++++++++++++----- .../Services/Models/Filters.cs | 12 ++++++++-- .../Views/Admin/Index.cshtml | 1 + 7 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs index 56bdd99c8..ef06f48f5 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/AdminController.cs @@ -1,14 +1,18 @@ using System.Linq; using System.Web.Mvc; +using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Services; using Orchard.AuditTrail.Services.Models; using Orchard.AuditTrail.ViewModels; +using Orchard.Collections; +using Orchard.ContentManagement; +using Orchard.Localization; using Orchard.Localization.Services; using Orchard.Security; using Orchard.UI.Navigation; namespace Orchard.AuditTrail.Controllers { - public class AdminController : Controller { + public class AdminController : Controller, IUpdateModel { private readonly IAuthorizer _authorizer; private readonly IAuditTrailManager _auditTrailManager; private readonly IOrchardServices _services; @@ -31,8 +35,14 @@ namespace Orchard.AuditTrail.Controllers { return new HttpUnauthorizedResult(); var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters); - var filters = Filters.From(Request.QueryString); + var filters = Filters.From(Request.QueryString, this); var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, filters, orderBy ?? AuditTrailOrderBy.DateDescending); + + // If there's a filter validation error, clear the results. + if (!ModelState.IsValid) { + pageOfData = new PageOfItems(Enumerable.Empty()); + } + var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); var filterDisplay = _auditTrailManager.BuildFilterDisplay(filters); var eventDescriptorsQuery = @@ -75,5 +85,13 @@ namespace Orchard.AuditTrail.Controllers { }; return View(viewModel); } + + bool IUpdateModel.TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) { + return TryUpdateModel(model, prefix, includeProperties, excludeProperties); + } + + void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) { + ModelState.AddModelError(key, errorMessage.Text); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 6e41a37f2..5046b9425 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Web.Mvc; using Orchard.AuditTrail.Models; using Orchard.AuditTrail.Providers.Content; using Orchard.AuditTrail.Services; @@ -45,12 +46,14 @@ namespace Orchard.AuditTrail.Drivers { if (settings.ShowAuditTrail) { results.Add(ContentShape("Parts_AuditTrail", () => { var pager = new Pager(_services.WorkContext.CurrentSite, null, null); - var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, ContentAuditTrailEventProvider.CreateFilters(part.Id)); + var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, ContentAuditTrailEventProvider.CreateFilters(part.Id, updater)); var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount); - var eventDescriptors = from c in _auditTrailManager.DescribeCategories() + var eventDescriptors = + from c in _auditTrailManager.DescribeCategories() from e in c.Events select e; - var recordViewModels = from record in pageOfData + var recordViewModels = + from record in pageOfData let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.FullEventName) where descriptor != null select new AuditTrailEventSummaryViewModel { @@ -59,6 +62,7 @@ namespace Orchard.AuditTrail.Drivers { CategoryDescriptor = descriptor.CategoryDescriptor, SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin") }; + return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape); })); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs index d0f507e0b..a199d3390 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventProvider.cs @@ -18,8 +18,8 @@ namespace Orchard.AuditTrail.Providers.Content { public const string Unpublished = "Unpublished"; public const string Removed = "Removed"; - public static Filters CreateFilters(int contentId) { - return new Filters { + public static Filters CreateFilters(int contentId, IUpdateModel updateModel) { + return new Filters(updateModel) { {"content", contentId.ToString(CultureInfo.InvariantCulture)} }; } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs index a9f9f0af0..1c60e7c75 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailManager.cs @@ -57,7 +57,6 @@ namespace Orchard.AuditTrail.Services { var query = _auditTrailRepository.Table; - if (filters != null) { var filterContext = new QueryFilterContext(query, filters); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs index f578030d4..de4a22499 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/CommonAuditTrailEventHandler.cs @@ -17,13 +17,9 @@ namespace Orchard.AuditTrail.Services { public override void Filter(QueryFilterContext context) { var userName = context.Filters.Get("username"); - var fromDate = context.Filters.Get("from.Date"); - var fromTime = context.Filters.Get("from.Time"); - var toDate = context.Filters.Get("to.Date"); - var toTime = context.Filters.Get("to.Time"); var category = context.Filters.Get("category"); - var from = _dateServices.ConvertFromLocalString(fromDate, fromTime).Earliest(); - var to = _dateServices.ConvertFromLocalString(toDate, toTime).Latest(); + var from = GetDateFromFilter(context.Filters, "From", "from").Earliest(); + var to = GetDateFromFilter(context.Filters, "To", "to").Latest(); var query = context.Query; if (!String.IsNullOrWhiteSpace(userName)) { @@ -59,5 +55,17 @@ namespace Orchard.AuditTrail.Services { context.FilterDisplay.Add(categoryFilterDisplay); context.FilterDisplay.Add(userNameFilterDisplay); } + + private DateTime? GetDateFromFilter(Filters filters, string fieldName, string prefix) { + try { + var dateString = filters.Get(prefix + ".Date"); + var timeString = filters.Get(prefix + ".Time"); + return _dateServices.ConvertFromLocalString(dateString, timeString); + } + catch (FormatException ex) { + filters.UpdateModel.AddModelError(prefix, T(@"Error parsing ""{0}"" date: {1}", fieldName, ex.Message)); + return null; + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs index 06ec9007a..946a96578 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/Models/Filters.cs @@ -1,10 +1,18 @@ using System.Collections.Generic; using System.Collections.Specialized; +using Orchard.ContentManagement; namespace Orchard.AuditTrail.Services.Models { public class Filters : Dictionary { - public static Filters From(NameValueCollection nameValues) { - var filters = new Filters(); + + public Filters(IUpdateModel updateModel) { + UpdateModel = updateModel; + } + + public IUpdateModel UpdateModel { get; set; } + + public static Filters From(NameValueCollection nameValues, IUpdateModel updateModel) { + var filters = new Filters(updateModel); foreach (string nameValue in nameValues) { filters.Add(nameValue, nameValues[nameValue]); diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index eafa3016d..a9769f103 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -12,6 +12,7 @@ Layout.Title = T("Audit Trail"); } +@Html.ValidationSummary() @using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) {
    @Display(Model.FilterDisplay) From 29b45d6e4547db357886118a4a8bfa2e5fdea620 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 23 Jul 2014 22:59:50 -0700 Subject: [PATCH 097/116] Consistifying tabs and spaces. --- .../Services/DefaultDateServices.cs | 240 +++++++++--------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/src/Orchard/Localization/Services/DefaultDateServices.cs b/src/Orchard/Localization/Services/DefaultDateServices.cs index 2877d4346..ee6a5fcd7 100644 --- a/src/Orchard/Localization/Services/DefaultDateServices.cs +++ b/src/Orchard/Localization/Services/DefaultDateServices.cs @@ -5,11 +5,11 @@ using Orchard.Settings; namespace Orchard.Localization.Services { - public class DefaultDateServices : IDateServices { + public class DefaultDateServices : IDateServices { private readonly IWorkContextAccessor _workContextAccessor; - private readonly IDateTimeFormatProvider _dateTimeLocalization; - private readonly ICalendarManager _calendarManager; + private readonly IDateTimeFormatProvider _dateTimeLocalization; + private readonly ICalendarManager _calendarManager; public DefaultDateServices( IWorkContextAccessor workContextAccessor, @@ -20,154 +20,154 @@ namespace Orchard.Localization.Services { _calendarManager = calendarManager; } - public virtual DateTime? ConvertToLocal(DateTime date) { - return ConvertToLocal(ToNullable(date)); - } + public virtual DateTime? ConvertToLocal(DateTime date) { + return ConvertToLocal(ToNullable(date)); + } - public virtual DateTime? ConvertToLocal(DateTime? date) { - if (!date.HasValue) { - return null; - } + public virtual DateTime? ConvertToLocal(DateTime? date) { + if (!date.HasValue) { + return null; + } var workContext = _workContextAccessor.GetContext(); return TimeZoneInfo.ConvertTimeFromUtc(date.Value, workContext.CurrentTimeZone); - } + } - public virtual string ConvertToLocalString(DateTime date, string nullText = null) { - return ConvertToLocalString(ToNullable(date), _dateTimeLocalization.LongDateTimeFormat, nullText); - } + public virtual string ConvertToLocalString(DateTime date, string nullText = null) { + return ConvertToLocalString(ToNullable(date), _dateTimeLocalization.LongDateTimeFormat, nullText); + } - public virtual string ConvertToLocalString(DateTime date, string format, string nullText = null) { - return ConvertToLocalString(ToNullable(date), format, nullText); - } + public virtual string ConvertToLocalString(DateTime date, string format, string nullText = null) { + return ConvertToLocalString(ToNullable(date), format, nullText); + } - public virtual string ConvertToLocalString(DateTime? date, string format, string nullText = null) { - var localDate = ConvertToLocal(date); - if (!localDate.HasValue) { - return nullText; - } + public virtual string ConvertToLocalString(DateTime? date, string format, string nullText = null) { + var localDate = ConvertToLocal(date); + if (!localDate.HasValue) { + return nullText; + } - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // formatting) and instead perform the calendar conversion ourselves. + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // formatting) and instead perform the calendar conversion ourselves. - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - var calendar = CurrentCalendar; - localDate = new DateTime(calendar.GetYear(localDate.Value), calendar.GetMonth(localDate.Value), calendar.GetDayOfMonth(localDate.Value), calendar.GetHour(localDate.Value), calendar.GetMinute(localDate.Value), calendar.GetSecond(localDate.Value)); - } + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + var calendar = CurrentCalendar; + localDate = new DateTime(calendar.GetYear(localDate.Value), calendar.GetMonth(localDate.Value), calendar.GetDayOfMonth(localDate.Value), calendar.GetHour(localDate.Value), calendar.GetMinute(localDate.Value), calendar.GetSecond(localDate.Value)); + } - return localDate.Value.ToString(format, cultureInfo); - } + return localDate.Value.ToString(format, cultureInfo); + } - public virtual string ConvertToLocalDateString(DateTime date, string nullText = null) { - return ConvertToLocalDateString(ToNullable(date), nullText); - } + public virtual string ConvertToLocalDateString(DateTime date, string nullText = null) { + return ConvertToLocalDateString(ToNullable(date), nullText); + } - public virtual string ConvertToLocalDateString(DateTime? date, string nullText = null) { - return ConvertToLocalString(date, _dateTimeLocalization.ShortDateFormat, nullText); - } + public virtual string ConvertToLocalDateString(DateTime? date, string nullText = null) { + return ConvertToLocalString(date, _dateTimeLocalization.ShortDateFormat, nullText); + } - public virtual string ConvertToLocalTimeString(DateTime date, string nullText = null) { - return ConvertToLocalTimeString(ToNullable(date), nullText); - } + public virtual string ConvertToLocalTimeString(DateTime date, string nullText = null) { + return ConvertToLocalTimeString(ToNullable(date), nullText); + } - public virtual string ConvertToLocalTimeString(DateTime? date, string nullText = null) { - return ConvertToLocalString(date, _dateTimeLocalization.ShortTimeFormat, nullText); - } + public virtual string ConvertToLocalTimeString(DateTime? date, string nullText = null) { + return ConvertToLocalString(date, _dateTimeLocalization.ShortTimeFormat, nullText); + } - public virtual DateTime? ConvertFromLocal(DateTime date) { - return ConvertFromLocal(ToNullable(date)); - } + public virtual DateTime? ConvertFromLocal(DateTime date) { + return ConvertFromLocal(ToNullable(date)); + } - public virtual DateTime? ConvertFromLocal(DateTime? date) { - if (!date.HasValue) { - return null; - } + public virtual DateTime? ConvertFromLocal(DateTime? date) { + if (!date.HasValue) { + return null; + } var workContext = _workContextAccessor.GetContext(); - return TimeZoneInfo.ConvertTimeToUtc(date.Value, workContext.CurrentTimeZone); - } + return TimeZoneInfo.ConvertTimeToUtc(date.Value, workContext.CurrentTimeZone); + } - public virtual DateTime? ConvertFromLocalString(string dateString) { - if (String.IsNullOrWhiteSpace(dateString)) { - return null; - } + public virtual DateTime? ConvertFromLocalString(string dateString) { + if (String.IsNullOrWhiteSpace(dateString)) { + return null; + } - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // parsing) and instead perform the calendar conversion ourselves. + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // parsing) and instead perform the calendar conversion ourselves. - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - } + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + } - var localDate = DateTime.Parse(dateString, CurrentCulture); + var localDate = DateTime.Parse(dateString, CurrentCulture); - if (!usingCultureCalendar) { - var calendar = CurrentCalendar; - localDate = calendar.ToDateTime(localDate.Year, localDate.Month, localDate.Day, localDate.Hour, localDate.Minute, localDate.Second, localDate.Millisecond); - } + if (!usingCultureCalendar) { + var calendar = CurrentCalendar; + localDate = calendar.ToDateTime(localDate.Year, localDate.Month, localDate.Day, localDate.Hour, localDate.Minute, localDate.Second, localDate.Millisecond); + } - return ConvertFromLocal(localDate); - } + return ConvertFromLocal(localDate); + } - public virtual DateTime? ConvertFromLocalString(string dateString, string timeString) { - if (String.IsNullOrWhiteSpace(dateString) && String.IsNullOrWhiteSpace(timeString)) { - return null; - } + public virtual DateTime? ConvertFromLocalString(string dateString, string timeString) { + if (String.IsNullOrWhiteSpace(dateString) && String.IsNullOrWhiteSpace(timeString)) { + return null; + } - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // parsing) and instead perform the calendar conversion ourselves. + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // parsing) and instead perform the calendar conversion ourselves. - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - } + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + } - var localDate = !String.IsNullOrWhiteSpace(dateString) ? DateTime.Parse(dateString, cultureInfo) : new DateTime(1980, 1, 1); - var localTime = !String.IsNullOrWhiteSpace(timeString) ? DateTime.Parse(timeString, cultureInfo) : new DateTime(1980, 1, 1, 12, 0, 0); - var localDateTime = new DateTime(localDate.Year, localDate.Month, localDate.Day, localTime.Hour, localTime.Minute, localTime.Second); + var localDate = !String.IsNullOrWhiteSpace(dateString) ? DateTime.Parse(dateString, cultureInfo) : new DateTime(1980, 1, 1); + var localTime = !String.IsNullOrWhiteSpace(timeString) ? DateTime.Parse(timeString, cultureInfo) : new DateTime(1980, 1, 1, 12, 0, 0); + var localDateTime = new DateTime(localDate.Year, localDate.Month, localDate.Day, localTime.Hour, localTime.Minute, localTime.Second); - if (!usingCultureCalendar) { - var calendar = CurrentCalendar; - localDateTime = calendar.ToDateTime(localDateTime.Year, localDateTime.Month, localDateTime.Day, localDateTime.Hour, localDateTime.Minute, localDateTime.Second, localDateTime.Millisecond); - } + if (!usingCultureCalendar) { + var calendar = CurrentCalendar; + localDateTime = calendar.ToDateTime(localDateTime.Year, localDateTime.Month, localDateTime.Day, localDateTime.Hour, localDateTime.Minute, localDateTime.Second, localDateTime.Millisecond); + } - return ConvertFromLocal(localDateTime); - } + return ConvertFromLocal(localDateTime); + } - protected virtual CultureInfo CurrentCulture { - get { + protected virtual CultureInfo CurrentCulture { + get { var workContext = _workContextAccessor.GetContext(); - return CultureInfo.GetCultureInfo(workContext.CurrentCulture); - } - } + return CultureInfo.GetCultureInfo(workContext.CurrentCulture); + } + } - protected virtual Calendar CurrentCalendar { - get { + protected virtual Calendar CurrentCalendar { + get { var workContext = _workContextAccessor.GetContext(); - if (!String.IsNullOrEmpty(workContext.CurrentCalendar)) - return _calendarManager.GetCalendarByName(workContext.CurrentCalendar); - return CurrentCulture.Calendar; - } - } + if (!String.IsNullOrEmpty(workContext.CurrentCalendar)) + return _calendarManager.GetCalendarByName(workContext.CurrentCalendar); + return CurrentCulture.Calendar; + } + } - protected virtual DateTime? ToNullable(DateTime date) { - return date == DateTime.MinValue ? new DateTime?() : new DateTime?(date); - } - } + protected virtual DateTime? ToNullable(DateTime date) { + return date == DateTime.MinValue ? new DateTime?() : new DateTime?(date); + } + } } \ No newline at end of file From bc13e3671a347a426980b5868c83dfa0d49e14e9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 23 Jul 2014 23:31:17 -0700 Subject: [PATCH 098/116] #198: Getting rid of buggy jquery driven placeholder text in favor of browser supported placeholder attribute. --- .../Core/Common/Views/EditorTemplates/DateTimeEditor.cshtml | 4 ++-- .../Views/EditorTemplates/DateTimeEditor.cshtml | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Orchard.Web/Core/Common/Views/EditorTemplates/DateTimeEditor.cshtml b/src/Orchard.Web/Core/Common/Views/EditorTemplates/DateTimeEditor.cshtml index d546a7b82..f72b093d0 100644 --- a/src/Orchard.Web/Core/Common/Views/EditorTemplates/DateTimeEditor.cshtml +++ b/src/Orchard.Web/Core/Common/Views/EditorTemplates/DateTimeEditor.cshtml @@ -6,12 +6,12 @@ @if (Model.ShowDate) { - @Html.EditorFor(m => m.Date) + @Html.TextBoxFor(m => m.Date, new { placeholder = T("Date").Text }) } @if (Model.ShowTime) { - @Html.EditorFor(m => m.Time) + @Html.TextBoxFor(m => m.Time, new { placeholder = T("Time").Text }) } @if (Model.ShowDate) { @Html.ValidationMessageFor(m => m.Date) } diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Views/EditorTemplates/DateTimeEditor.cshtml b/src/Orchard.Web/Modules/Orchard.jQuery/Views/EditorTemplates/DateTimeEditor.cshtml index 6e0e3efc6..d39518771 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Views/EditorTemplates/DateTimeEditor.cshtml +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Views/EditorTemplates/DateTimeEditor.cshtml @@ -9,17 +9,16 @@ Script.Require("jQueryCalendars_All").AtFoot(); Script.Require("jQueryCalendars_Picker_Ext").AtFoot(); Script.Require("jQueryTimeEntry").AtFoot(); - Script.Require("jQueryDateTimeEditor").AtFoot(); } @if (Model.ShowDate) { - @Html.EditorFor(m => m.Date) + @Html.TextBoxFor(m => m.Date, new { placeholder = T("Date").Text, @class = "text" }) } @if (Model.ShowTime) { - @Html.EditorFor(m => m.Time) + @Html.TextBoxFor(m => m.Time, new { placeholder = T("Time").Text, @class = "text" }) } @if (Model.ShowDate) { @Html.ValidationMessageFor(m => m.Date) } From dd8212e2b7cef636bffc2e52cae721588a5fd3c7 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 23 Jul 2014 23:59:17 -0700 Subject: [PATCH 099/116] Handling addition case for attribute as well as element nodes. --- .../Providers/Content/DiffGramAnalyzer.cs | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index bd22deaa9..b14f7d2c9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -77,19 +77,29 @@ namespace Orchard.AuditTrail.Providers.Content { } break; case "add": - string nodeName = reader.GetAttribute("name"); - string addedContent = null; - reader.Read(); - if (reader.NodeType != XmlNodeType.EndElement) { - nodeName = reader.Name; - addedContent = reader.ReadElementContentAsString(); - } - yield return - new DiffNode { - Type = DiffType.Addition, - Context = BuildContextName(stack, nodeName), - Current = addedContent + if (isAttributeChange) { + var attributeName = match.Substring(1); + var value = reader.ReadElementContentAsString(); + + readNext = false; + yield return new DiffNode { + Type = DiffType.Addition, + Context = BuildContextName(stack, attributeName), + Current = value }; + } + else { + var elementName = currentElement.Name.ToString(); + var content = reader.ReadElementContentAsString(); + + readNext = false; + yield return + new DiffNode { + Type = DiffType.Addition, + Context = BuildContextName(stack, elementName), + Current = content + }; + } break; } } From d2d0c477a3076d7e0e0a6004c7f8085901a02364 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 00:00:22 -0700 Subject: [PATCH 100/116] #196: Bugfixing and rendering content item type and title. --- .../Content/ContentAuditTrailEventShapes.cs | 2 +- .../Providers/Content/GlobalContentHandler.cs | 4 +--- .../AuditTrailEvent-Content.SummaryAdmin.cshtml | 15 +++++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs index ce2d9659a..c2392bf4a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/ContentAuditTrailEventShapes.cs @@ -22,7 +22,7 @@ namespace Orchard.AuditTrail.Providers.Content { builder.Describe("AuditTrailEvent").OnDisplaying(context => { var record = (AuditTrailEventRecord)context.Shape.Record; - if (record.Category != "Content" || context.ShapeMetadata.DisplayType != "Detail") + if (record.Category != "Content") return; var eventData = (IDictionary)context.Shape.EventData; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 6244b4e84..31f47fe51 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -67,11 +67,9 @@ namespace Orchard.AuditTrail.Providers.Content { var eventData = new Dictionary { {"ContentId", content.Id}, {"ContentIdentity", _contentManager.GetItemMetadata(content).Identity.ToString()}, + {"ContentType", content.ContentItem.ContentType}, {"VersionId", content.ContentItem.VersionRecord.Id}, {"VersionNumber", content.ContentItem.VersionRecord.Number}, - {"Published", content.ContentItem.VersionRecord.Published}, - {"Latest", content.ContentItem.VersionRecord.Latest}, - {"Title", title} }; if (previousContentItemVersion != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index 7e2e123b4..a14cf29cd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -1,13 +1,16 @@ -@using Orchard.AuditTrail.Helpers +@using Orchard.ContentManagement @{ var eventData = (IDictionary) Model.EventData; - var contentItemId = eventData.Get("ContentId"); - var contentItemVersionNumber = eventData.Get("VersionNumber"); - var isPublished = eventData.Get("Published"); - var isLatest = eventData.Get("Latest"); + var contentItem = (ContentItem) Model.ContentItem; + var contentItemId = contentItem.Id; + var contentItemVersionNumber = contentItem.Version; + var contentType = contentItem.ContentType; + var title = Html.ItemDisplayText(contentItem); + var isPublished = contentItem.VersionRecord.Published; + var isLatest = contentItem.VersionRecord.Latest; }
    - @T("Version {0}", contentItemVersionNumber) + @T("{0} - {1} (version {2})", contentType, title, contentItemVersionNumber) @if (isPublished) { @T(" - ") @T("View") From 799bd79d20c18e623be76f544edb998193543f07 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 00:12:26 -0700 Subject: [PATCH 101/116] More content event bug fixing. --- .../Providers/Content/GlobalContentHandler.cs | 1 + .../AuditTrailEvent-Content.SummaryAdmin.cshtml | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 31f47fe51..8b3e392da 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -70,6 +70,7 @@ namespace Orchard.AuditTrail.Providers.Content { {"ContentType", content.ContentItem.ContentType}, {"VersionId", content.ContentItem.VersionRecord.Id}, {"VersionNumber", content.ContentItem.VersionRecord.Number}, + {"Published", content.ContentItem.VersionRecord.Published}, }; if (previousContentItemVersion != null) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index a14cf29cd..5409189e8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -1,19 +1,20 @@ -@using Orchard.ContentManagement +@using Orchard.AuditTrail.Helpers +@using Orchard.ContentManagement @{ var eventData = (IDictionary) Model.EventData; var contentItem = (ContentItem) Model.ContentItem; var contentItemId = contentItem.Id; - var contentItemVersionNumber = contentItem.Version; + var eventVersionNumber = eventData.Get("VersionNumber"); + var eventIsPublished = eventData.Get("Published"); var contentType = contentItem.ContentType; var title = Html.ItemDisplayText(contentItem); - var isPublished = contentItem.VersionRecord.Published; - var isLatest = contentItem.VersionRecord.Latest; + var isLatest = contentItem.VersionRecord.Number == eventVersionNumber; }
    - @T("{0} - {1} (version {2})", contentType, title, contentItemVersionNumber) - @if (isPublished) { + @T("{0} - {1} (version {2})", contentType, title, eventVersionNumber) + @if (eventIsPublished) { @T(" - ") - @T("View") + @T("View") } else if (isLatest) { @T(" - ") From e8944970160a01d12a98d4a986c9b2b1d41d262e Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 00:48:54 -0700 Subject: [PATCH 102/116] #197: Show audit trail event comment only in read only view. --- .../Controllers/ContentController.cs | 7 +++++++ .../Drivers/AuditTrailPartDriver.cs | 14 +++++++++++--- .../Orchard.AuditTrail/Models/AuditTrailPart.cs | 6 ++++-- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 1 + .../Providers/Content/AuditTrailEventHandler.cs | 1 - .../Providers/Content/GlobalContentHandler.cs | 2 -- .../ViewModels/AuditTrailCommentViewModel.cs | 5 +++++ .../Parts.AuditTrail.Comment.cshtml | 2 +- 8 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCommentViewModel.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs index c3dfcf16f..6ae87c618 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Controllers/ContentController.cs @@ -1,4 +1,5 @@ using System.Web.Mvc; +using Orchard.AuditTrail.Models; using Orchard.ContentManagement; using Orchard.Security; using Orchard.UI.Admin; @@ -19,6 +20,12 @@ namespace Orchard.AuditTrail.Controllers { if (!_authorizer.Authorize(Core.Contents.Permissions.ViewContent, contentItem)) return new HttpUnauthorizedResult(); + var auditTrailPart = contentItem.As(); + + if (auditTrailPart != null) { + auditTrailPart.ShowComment = true; + } + var editor = _contentManager.BuildEditor(contentItem); return View(editor); } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs index 5046b9425..9dddc12a9 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Drivers/AuditTrailPartDriver.cs @@ -32,10 +32,18 @@ namespace Orchard.AuditTrail.Drivers { if (settings.ShowAuditTrailCommentInput) { results.Add(ContentShape("Parts_AuditTrail_Comment", () => { - if (updater != null) { - updater.TryUpdateModel(part, Prefix, null, null); + var viewModel = new AuditTrailCommentViewModel(); + + if (part.ShowComment) { + viewModel.Comment = part.Comment; } - return shapeHelper.EditorTemplate(Model: part, TemplateName: "Parts.AuditTrail.Comment", Prefix: Prefix); + + if (updater != null) { + if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { + part.Comment = viewModel.Comment; + } + } + return shapeHelper.EditorTemplate(Model: viewModel, TemplateName: "Parts.AuditTrail.Comment", Prefix: Prefix); })); } if (_services.Authorizer.Authorize(Permissions.ViewAuditTrail)) { diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs index 5a425c949..ed3d0f4a1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Models/AuditTrailPart.cs @@ -3,8 +3,10 @@ namespace Orchard.AuditTrail.Models { public class AuditTrailPart : ContentPart { public string Comment { - get { return this.Retrieve(x => x.Comment); } - set { this.Store(x => x.Comment, value); } + get { return RetrieveVersioned("Comment"); } + set { StoreVersioned("Comment", value); } } + + public bool ShowComment { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index b38eef750..5eb95f6bc 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -255,6 +255,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs index 6f3388fe3..f32e3dcc0 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/AuditTrailEventHandler.cs @@ -13,7 +13,6 @@ namespace Orchard.AuditTrail.Providers.Content { return; context.Comment = auditTrailPart.Comment; - auditTrailPart.Comment = null; // Reset the comment. } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs index 8b3e392da..baf4d0ce8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/GlobalContentHandler.cs @@ -58,8 +58,6 @@ namespace Orchard.AuditTrail.Providers.Content { if (blackList.Contains(content.ContentItem.ContentType)) return; - var title = _contentManager.GetItemMetadata(content).DisplayText; - var properties = new Dictionary { {"Content", content} }; diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCommentViewModel.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCommentViewModel.cs new file mode 100644 index 000000000..3e5799f1f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/ViewModels/AuditTrailCommentViewModel.cs @@ -0,0 +1,5 @@ +namespace Orchard.AuditTrail.ViewModels { + public class AuditTrailCommentViewModel { + public string Comment { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml index 3cb48fcb0..b06864dd8 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/EditorTemplates/Parts.AuditTrail.Comment.cshtml @@ -1,4 +1,4 @@ -@model Orchard.AuditTrail.Models.AuditTrailPart +@model Orchard.AuditTrail.ViewModels.AuditTrailCommentViewModel
    @Html.LabelFor(m => m.Comment, T("Comment")) @Html.TextAreaFor(m => m.Comment) From 192e57c739b70cf23c321e9a831065ff5f7d4319 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 00:53:17 -0700 Subject: [PATCH 103/116] #203: Setting default audit trail part settings. --- .../Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs index 25f9c4a75..c1efd4f00 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Settings/AuditTrailPartSettings.cs @@ -3,6 +3,12 @@ using Orchard.ContentManagement.MetaData.Builders; namespace Orchard.AuditTrail.Settings { public class AuditTrailPartSettings { + public AuditTrailPartSettings() { + ShowAuditTrail = true; + ShowAuditTrailCommentInput = true; + ShowAuditTrailLink = true; + } + public bool ShowAuditTrailLink { get; set; } public bool ShowAuditTrail { get; set; } public bool ShowAuditTrailCommentInput { get; set; } From be37ee54dcbd7813650147e18b5540277ea790ab Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 12:02:04 -0700 Subject: [PATCH 104/116] Reversing breaking fix and using OuterXML as content to include any attributes as well as element contents. --- .../Providers/Content/DiffGramAnalyzer.cs | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs index b14f7d2c9..570362a2b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Providers/Content/DiffGramAnalyzer.cs @@ -77,29 +77,19 @@ namespace Orchard.AuditTrail.Providers.Content { } break; case "add": - if (isAttributeChange) { - var attributeName = match.Substring(1); - var value = reader.ReadElementContentAsString(); - - readNext = false; - yield return new DiffNode { - Type = DiffType.Addition, - Context = BuildContextName(stack, attributeName), - Current = value + var nodeName = reader.GetAttribute("name"); + var addedContent = default(string); + reader.Read(); + if (reader.NodeType != XmlNodeType.EndElement) { + nodeName = reader.Name; + addedContent = reader.ReadOuterXml(); + } + yield return + new DiffNode { + Type = DiffType.Addition, + Context = BuildContextName(stack, nodeName), + Current = addedContent }; - } - else { - var elementName = currentElement.Name.ToString(); - var content = reader.ReadElementContentAsString(); - - readNext = false; - yield return - new DiffNode { - Type = DiffType.Addition, - Context = BuildContextName(stack, elementName), - Current = content - }; - } break; } } From 4ba6bcdbc0d9ef7fa65e30d6d0cc52b9d5712bb9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 24 Jul 2014 21:18:08 -0700 Subject: [PATCH 105/116] Removing unused script. --- .../Orchard.jQuery/Orchard.jQuery.csproj | 1 - .../Modules/Orchard.jQuery/ResourceManifest.cs | 1 - .../Scripts/jquery-datetime-editor.js | 18 ------------------ 3 files changed, 20 deletions(-) delete mode 100644 src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-datetime-editor.js diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Orchard.jQuery.csproj b/src/Orchard.Web/Modules/Orchard.jQuery/Orchard.jQuery.csproj index 1c5239601..c0a4dc25c 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Orchard.jQuery.csproj +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Orchard.jQuery.csproj @@ -256,7 +256,6 @@ - diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs b/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs index 62467d414..3b5289c92 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs +++ b/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs @@ -77,7 +77,6 @@ namespace Orchard.jQuery { manifest.DefineStyle("jQueryTimeEntry").SetUrl("jquery.timeentry.css").SetVersion("1.5.2"); // jQuery Date/Time Editor Enhancements - manifest.DefineScript("jQueryDateTimeEditor").SetUrl("jquery-datetime-editor.js").SetDependencies("jQuery"); manifest.DefineStyle("jQueryDateTimeEditor").SetUrl("jquery-datetime-editor.css").SetDependencies("DateTimeEditor"); // jQuery File Upload diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-datetime-editor.js b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-datetime-editor.js deleted file mode 100644 index 837640b35..000000000 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-datetime-editor.js +++ /dev/null @@ -1,18 +0,0 @@ -var clearHint = function (self) { self.removeClass("hinted"); if (self.val() == self.data("hint")) { self.val("") } }; -var resetHint = function (self) { setTimeout(function () { if (!self.val()) { self.addClass("hinted").val(self.data("hint")) } }, 300) }; - -$(document).ready(function () { - $("label.forpicker").each(function () { - var $this = $(this); - var pickerInput = $("#" + $this.attr("for")); - pickerInput.data("hint", $this.text()); - if (!pickerInput.val()) { - pickerInput.addClass("hinted") - .val(pickerInput.data("hint")) - .change(function () { clearHint($(this)); }) - .focus(function () { clearHint($(this)); }) - .blur(function () { resetHint($(this)); }); - $this.closest("form").submit(function () { clearHint(pickerInput); pickerInput = 0; }); - } - }); -}); \ No newline at end of file From 3d284eece8cb449e614aa88e45553c5650742dbe Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 15:39:56 -0700 Subject: [PATCH 106/116] Implementing reusable MediaLibraryPicker shape. --- .../Orchard.MediaLibrary.csproj | 4 + .../Scripts/media-library-picker.js | 110 ++++++++++++ .../Fields/MediaLibraryPicker.Edit.cshtml | 162 +----------------- .../Views/MediaLibraryPicker.cshtml | 59 +++++++ 4 files changed, 180 insertions(+), 155 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js create mode 100644 src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj index c628bf094..2f25912e9 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj @@ -76,6 +76,7 @@ + @@ -346,6 +347,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js new file mode 100644 index 000000000..e451a07bd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js @@ -0,0 +1,110 @@ +(function($) { + + $(".media-library-picker-field").each(function() { + var element = $(this); + var multiple = element.data("multiple"); + var removeText = element.data("remove-text"); + var removePrompt = element.data("remove-prompt"); + var editText = element.data("edit-text"); + var dirtyText = element.data("dirty-text"); + var pipe = element.data("pipe"); + var returnUrl = element.data("return-url"); + var addUrl = element.data("add-url"); + var addButton = element.find(".button.add"); + var template = + '
  • {thumbnail}

    {title}

    ' + removeText + '' + pipe + '' + editText + '
  • '; + + var refreshIds = function() { + var id = element.find('.selected-ids'); + id.val(''); + element.find(".media-library-picker-item").each(function() { + id.val(id.val() + "," + $(this).attr("data-id")); + }); + + var itemsCount = element.find(".media-library-picker-item").length; + + if(!multiple && itemsCount > 0) { + addButton.hide(); + } + else { + addButton.show(); + } + }; + + window.mediaLibraryDirty = false; + var showSaveMsg = function() { + element.find('.media-library-picker-message').show(); + window.mediaLibraryDirty = true; + }; + if (!window.mediaLibraryNavigateAway) { + $(window).on("beforeunload", window.mediaLibraryNavigateAway = function() { + if (window.mediaLibraryDirty) { + return dirtyText; + } + }); + element.closest("form").on("submit", function() { + window.mediaLibraryDirty = false; + }); + } + + refreshIds(); + + addButton.click(function () { + var url = addUrl; + $.colorbox({ + href: url, + iframe: true, + reposition: true, + width: "100%", + height: "100%", + onLoad: function() { // hide the scrollbars from the main window + $('html, body').css('overflow', 'hidden'); + $('#cboxClose').remove(); + }, + onClosed: function() { + $('html, body').css('overflow', ''); + var selectedData = $.colorbox.selectedData; + if (selectedData == null) // Dialog cancelled, do nothing + return; + + var selectionLength = multiple ? selectedData.length : Math.min(selectedData.length, 1); + + for (var i = 0; i < selectionLength ; i++) { + var tmpl = template + .replace(/\{contentItemId\}/g, selectedData[i].id) + .replace(/\{thumbnail\}/g, selectedData[i].thumbnail) + .replace(/\{title\}/g, selectedData[i].title) + .replace(/\{editLink\}/g, selectedData[i].editLink); + var content = $(tmpl); + element.find('.media-library-picker.items ul').append(content); + } + + refreshIds(); + + if (selectedData.length) { + showSaveMsg(); + } + } + }); + + }); + + element.on("click",'.media-library-picker-remove', function(e) { + e.preventDefault(); + if (!confirm(removePrompt)) return false; + $(this).closest('li').remove(); + refreshIds(); + showSaveMsg(); + return false; + }); + + element.find(".media-library-picker.items ul").sortable({ + handle: '.thumbnail', + stop: function() { + refreshIds(); + showSaveMsg(); + } + }).disableSelection(); + }); + +})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml index 3ae435583..33ecc2ecd 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml @@ -1,160 +1,12 @@ @model Orchard.MediaLibrary.ViewModels.MediaLibraryPickerFieldViewModel -@using Orchard.ContentManagement -@using Orchard.Utility.Extensions; @using Orchard.MediaLibrary.Settings; - @{ - Script.Require("jQueryUI_Sortable").AtFoot(); - Style.Include("media-library-picker-admin.css"); - - Script.Require("jQueryColorBox").AtFoot(); - Style.Require("jQueryColorBox"); - var settings = Model.Field.PartFieldDefinition.Settings.GetModel(); - var contentManager = WorkContext.Resolve(); - var fieldIdForSelectedIds = Html.FieldIdFor(m => m.SelectedIds); - var fieldIdForIds = Html.FieldIdFor(m => m.Field.Ids); } - -
    - -
    @T("You need to save your changes.")
    -
    -
      - @foreach (var contentItem in Model.ContentItems) { - var editRouteValues = contentManager.GetItemMetadata(contentItem).EditorRouteValues; - var editUrl = Url.Action( - Convert.ToString(editRouteValues["action"]), - editRouteValues.Merge(new RouteValueDictionary { { "ReturnUrl", Request.RawUrl } })); -
    • -
      -
      - @Display(contentManager.BuildDisplay(contentItem, "Thumbnail")) -
      -

      @Html.ItemDisplayText(contentItem)

      -
      - -
      -
      - @T("Remove")@T(" | ") - @T("Edit") -
    • - } -
    -
    - -
    - @T("Add") -
    - - @Html.HiddenFor(m => m.SelectedIds) - @settings.Hint -
    - -@using (Script.Foot()) { - -} \ No newline at end of file +@Display.MediaLibraryPicker( + FieldName: Html.FieldNameFor(m => m.SelectedIds), + DisplayName: Model.Field.DisplayName, + Multiple: settings.Multiple, + Required: settings.Required, + Hint: settings.Hint, + ContentItems: Model.ContentItems) \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml new file mode 100644 index 000000000..b5a7bb466 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml @@ -0,0 +1,59 @@ +@using Orchard.ContentManagement +@using Orchard.Utility.Extensions; + +@{ + Style.Include("media-library-picker-admin.css"); + Style.Require("jQueryColorBox"); + Script.Require("jQueryUI_Sortable").AtFoot(); + Script.Require("jQueryColorBox").AtFoot(); + Script.Include("media-library-picker.js").AtFoot(); + + var fieldName = (string) Model.FieldName; + var displayName = (string) Model.DisplayName; + var multiple = (bool)(Model.Multiple ?? false); + var required = (bool)(Model.Required ?? false); + var hint = (string) Model.Hint; + var contentItems = (IEnumerable)Model.ContentItems ?? Enumerable.Empty(); + var contentManager = WorkContext.Resolve(); +} + +
    + +
    @T("You need to save your changes.")
    +
    +
      + @foreach (var contentItem in contentItems) { + var editRouteValues = contentManager.GetItemMetadata(contentItem).EditorRouteValues; + var editUrl = Url.Action( + Convert.ToString(editRouteValues["action"]), + editRouteValues.Merge(new RouteValueDictionary { { "ReturnUrl", Request.RawUrl } })); +
    • +
      +
      + @Display(BuildDisplay(contentItem, "Thumbnail")) +
      +

      @Html.ItemDisplayText(contentItem)

      +
      + +
      +
      + @T("Remove")@T(" | ") + @T("Edit") +
    • + } +
    +
    +
    + @T("Add") +
    + x.Id))" class="selected-ids" /> + @hint +
    \ No newline at end of file From 6e4fcd6a2a56790f5626962cafd6376ffe2e49a9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 15:40:30 -0700 Subject: [PATCH 107/116] Consistifying line endings. --- .../Scripts/media-library.js | 800 +++++++++--------- 1 file changed, 400 insertions(+), 400 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js index 0b9283e1f..42298d8d7 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js @@ -1,51 +1,51 @@ -var enhanceViewModel = function(viewModel) { - // extension point for other modules to alter the view model -}; - -var baseViewModel = function() { - -}; - -$(function () { - (function (settings) { - +var enhanceViewModel = function(viewModel) { + // extension point for other modules to alter the view model +}; + +var baseViewModel = function() { + +}; + +$(function () { + (function (settings) { + function attachFolderTitleDropEvent (elements) { elements.droppable({ accept: function () { - var targetId = $(this).data('term-id'); + var targetId = $(this).data('term-id'); return targetId != viewModel.displayed(); - }, + }, over: function (event, ui) { - $(ui.helper).addClass('over'); + $(ui.helper).addClass('over'); $(this).addClass('dropping'); - }, + }, out: function (event, ui) { - $(ui.helper).removeClass('over'); + $(ui.helper).removeClass('over'); $(this).removeClass('dropping'); - }, - tolerance: "pointer", + }, + tolerance: "pointer", drop: function () { - $(this).removeClass('dropping'); - var folderPath = $(this).data('media-path'); - + $(this).removeClass('dropping'); + var folderPath = $(this).data('media-path'); + if (folderPath == viewModel.displayed()) { return; - } - - var ids = []; - viewModel.selection().forEach(function (item) { ids.push(item.data.id); }); - var url = settings.moveActionUrl; - - console.log(folderPath); - + } + + var ids = []; + viewModel.selection().forEach(function (item) { ids.push(item.data.id); }); + var url = settings.moveActionUrl; + + console.log(folderPath); + $.ajax({ - type: "POST", - url: url, - dataType: "json", - traditional: true, + type: "POST", + url: url, + dataType: "json", + traditional: true, data: { - folderPath: folderPath, - mediaItemIds: ids, + folderPath: folderPath, + mediaItemIds: ids, __RequestVerificationToken: settings.antiForgeryToken }, }).done(function (result) { @@ -54,90 +54,90 @@ $(function () { viewModel.results.remove(function (item) { return ids.indexOf(item.data.id) != -1; }); - } - + } + viewModel.clearSelection(); } else { - alert(errorMessage); + alert(errorMessage); console.log('failed to move media items: ' + result.toString()); } }).fail(function (result) { - alert(errorMessage); + alert(errorMessage); console.log('failed to move media items: ' + result.toString()); }); } }); - }; - - var listWidth = $('#media-library-main-list').width(); - var listHeight = $('#media-library-main-list').height(); - var itemSize = $('.thumbnail').first().width(); - var draftText = $("#media-library").data("draft-text"); - - var itemsPerRow = Math.floor(listWidth / itemSize); - var itemsPerColumn = Math.ceil(listHeight / itemSize); - - var pageCount = itemsPerRow * itemsPerColumn; - - function mediaPartViewModel(data) { - var self = this; - - // values - self.data = data; - - //id, - //contentType, - //contentTypeClass, - //title, - //alternateText, - //caption, - //resource, - //mimeType, - //mimeTypeClass, - //thumbnail, - //editLink, - - self.hasFocus = ko.observable(); - self.selected = ko.observable(); - self.status = ko.observable(''); - self.summary = ko.observable(''); - self.cssClass = ko.computed(function() { - var css = ''; - if (self.selected()) { - css += ' selected'; - } - - if (self.hasFocus()) { - css += ' has-focus'; - } - - return css; - }); - - self.publicationStatus = ko.computed(function() { - return self.data.published ? "" : draftText; - }); - - // operations - self.setData = function(value) { - self.data = value; - }; - } - - function mediaIndexViewModel() { - var self = this; - - // placeholder function called to retrieve content when scrolling - self.loadMediaItemsUrl = function (folderPath, skip, count, order, mediaType) { - }; - - // values - self.selection = ko.observableArray([]); - self.focus = ko.observable(); - self.results = ko.observableArray(); - self.displayed = ko.observable(); - self.mediaItemsCount = 0; - self.orderMedia = ko.observableArray(['created']); + }; + + var listWidth = $('#media-library-main-list').width(); + var listHeight = $('#media-library-main-list').height(); + var itemSize = $('.thumbnail').first().width(); + var draftText = $("#media-library").data("draft-text"); + + var itemsPerRow = Math.floor(listWidth / itemSize); + var itemsPerColumn = Math.ceil(listHeight / itemSize); + + var pageCount = itemsPerRow * itemsPerColumn; + + function mediaPartViewModel(data) { + var self = this; + + // values + self.data = data; + + //id, + //contentType, + //contentTypeClass, + //title, + //alternateText, + //caption, + //resource, + //mimeType, + //mimeTypeClass, + //thumbnail, + //editLink, + + self.hasFocus = ko.observable(); + self.selected = ko.observable(); + self.status = ko.observable(''); + self.summary = ko.observable(''); + self.cssClass = ko.computed(function() { + var css = ''; + if (self.selected()) { + css += ' selected'; + } + + if (self.hasFocus()) { + css += ' has-focus'; + } + + return css; + }); + + self.publicationStatus = ko.computed(function() { + return self.data.published ? "" : draftText; + }); + + // operations + self.setData = function(value) { + self.data = value; + }; + } + + function mediaIndexViewModel() { + var self = this; + + // placeholder function called to retrieve content when scrolling + self.loadMediaItemsUrl = function (folderPath, skip, count, order, mediaType) { + }; + + // values + self.selection = ko.observableArray([]); + self.focus = ko.observable(); + self.results = ko.observableArray(); + self.displayed = ko.observable(); + self.mediaItemsCount = 0; + self.orderMedia = ko.observableArray(['created']); self.mediaType = ko.observableArray([]); self.mediaFolders = ko.observableArray([]); @@ -164,73 +164,73 @@ $(function () { self.mediaPendingRequest(value); } }); - - self.getMediaItems = function (count, append) { - var folderPath = self.displayed() || ''; - - if (self.mediaPendingRequest()) { - return; - } - - if (append) { - if (self.results().length > 0 && self.results().length >= self.mediaItemsCount) { - return; - } - } else { - self.results([]); - } - - self.pendingRequest(true); - - var url = self.loadMediaItemsUrl(folderPath, self.results().length, count, self.orderMedia(), self.mediaType()); - console.log(url); - - $.ajax({ - type: "GET", - url: url, - cache: false - }).done(function(data) { + + self.getMediaItems = function (count, append) { + var folderPath = self.displayed() || ''; + + if (self.mediaPendingRequest()) { + return; + } + + if (append) { + if (self.results().length > 0 && self.results().length >= self.mediaItemsCount) { + return; + } + } else { + self.results([]); + } + + self.pendingRequest(true); + + var url = self.loadMediaItemsUrl(folderPath, self.results().length, count, self.orderMedia(), self.mediaType()); + console.log(url); + + $.ajax({ + type: "GET", + url: url, + cache: false + }).done(function(data) { var mediaItems = data.mediaItems; var mediaItemsFolderPath = data.folderPath; - + if (mediaItemsFolderPath !== self.displayed()) { return; - } - - self.mediaItemsCount = data.mediaItemsCount; - for (var i = 0; i < mediaItems.length; i++) { - var item = new mediaPartViewModel(mediaItems[i]); - self.results.push(item); - - // pre-select result which are already part of the selection - var selection = self.selection(); - for (var j = 0; j < selection.length; j++) { - if (selection[j].data.id == item.data.id) { - viewModel.toggleSelect(item, true); - } - } - } - }).fail(function(data) { - console.error(data); - }).always(function() { - self.pendingRequest(false); - }); - }; - - self.clearSelection = function() { - this.focus(null); - // unselect previous elements - self.selection().forEach(function(item) { - item.selected(false); - }); - - self.selection([]); - }; - - self.focus.subscribe(function(oldValue) { - if (oldValue) { - oldValue.hasFocus(false); - } + } + + self.mediaItemsCount = data.mediaItemsCount; + for (var i = 0; i < mediaItems.length; i++) { + var item = new mediaPartViewModel(mediaItems[i]); + self.results.push(item); + + // pre-select result which are already part of the selection + var selection = self.selection(); + for (var j = 0; j < selection.length; j++) { + if (selection[j].data.id == item.data.id) { + viewModel.toggleSelect(item, true); + } + } + } + }).fail(function(data) { + console.error(data); + }).always(function() { + self.pendingRequest(false); + }); + }; + + self.clearSelection = function() { + this.focus(null); + // unselect previous elements + self.selection().forEach(function(item) { + item.selected(false); + }); + + self.selection([]); + }; + + self.focus.subscribe(function(oldValue) { + if (oldValue) { + oldValue.hasFocus(false); + } }, this, "beforeChange"); self.afterRenderMediaFolderTemplate = function(elements, model) { @@ -238,104 +238,104 @@ $(function () { attachFolderTitleDropEvent(childTitles); }; - self.focus.subscribe(function(newValue) { - if (newValue) { - newValue.hasFocus(true); - - // load summary admin if not alreay done - if (newValue.summary() == '') { - var id = newValue.data.id; - var url = settings.mediaItemActionUrl + '/' + id; - - $.ajax({ - type: "GET", - url: url, - cache: false - }).done(function(data) { - newValue.summary(data); - }); - } - } - }); - - self.displayFolder = function(folderPath) { - self.results([]); - self.displayed(folderPath); - - self.loadMediaItemsUrl = function (f, skip, count, order, mediaType) { - return settings.mediaItemsActionUrl + '?folderPath=' + encodeURIComponent(f) + '&skip=' + skip + '&count=' + count + '&order=' + order + '&mediaType=' + mediaType; - }; - + self.focus.subscribe(function(newValue) { + if (newValue) { + newValue.hasFocus(true); + + // load summary admin if not alreay done + if (newValue.summary() == '') { + var id = newValue.data.id; + var url = settings.mediaItemActionUrl + '/' + id; + + $.ajax({ + type: "GET", + url: url, + cache: false + }).done(function(data) { + newValue.summary(data); + }); + } + } + }); + + self.displayFolder = function(folderPath) { + self.results([]); + self.displayed(folderPath); + + self.loadMediaItemsUrl = function (f, skip, count, order, mediaType) { + return settings.mediaItemsActionUrl + '?folderPath=' + encodeURIComponent(f) + '&skip=' + skip + '&count=' + count + '&order=' + order + '&mediaType=' + mediaType; + }; + self.getMediaItems(pageCount); - }; - - self.selectFolder = function (folderPath) { - History.pushState({ action: 'displayFolder', folderPath: folderPath }, '', '?folderPath=' + folderPath); - self.displayFolder(folderPath); - }; - - self.selectRecent = function() { - History.pushState({ action: 'selectRecent' }, '', '?recent'); - - self.loadMediaItemsUrl = function (folderPath, skip, count, order, mediaType) { - return settings.recentMediaItemsActionUrl + '?skip=' + skip + '&count=' + count + '&order=' + order + '&mediaType=' + mediaType; - }; - - self.results([]); - self.displayed(null); - self.getMediaItems(pageCount); - }; - - self.toggleSelect = function(searchResult, force) { - var index = $.inArray(searchResult, self.selection()); - if (index == -1 || force) { - self.selection.remove(function(item) { return item.data.id == searchResult.data.id; }); - self.selection.push(searchResult); - searchResult.selected(true); - } else { - self.selection.remove(searchResult); - searchResult.selected(false); - } - - this.focus(searchResult); - }; - - self.select = function(searchResult) { - var index = $.inArray(searchResult, self.selection()); - if (index == -1) { - self.clearSelection(); - self.selection([searchResult]); - searchResult.selected(true); - } - - this.focus(searchResult); - }; - - self.scrolled = function(data, event) { - var elem = event.target; - if (elem.scrollTop > (elem.scrollHeight - elem.offsetHeight - 300)) { - self.getMediaItems(pageCount, true); - } - }; - - self.importMedia = function() { - var url = settings.importActionUrl + '?folderPath=' + encodeURIComponent(self.displayed()); - window.location = url; - }; - - var selectFolderOrRecent = function () { - if (self.displayed()) { - self.selectFolder(self.displayed()); - } else { - self.selectRecent(); - } - }; - self.orderMedia.subscribe(selectFolderOrRecent); + }; + + self.selectFolder = function (folderPath) { + History.pushState({ action: 'displayFolder', folderPath: folderPath }, '', '?folderPath=' + folderPath); + self.displayFolder(folderPath); + }; + + self.selectRecent = function() { + History.pushState({ action: 'selectRecent' }, '', '?recent'); + + self.loadMediaItemsUrl = function (folderPath, skip, count, order, mediaType) { + return settings.recentMediaItemsActionUrl + '?skip=' + skip + '&count=' + count + '&order=' + order + '&mediaType=' + mediaType; + }; + + self.results([]); + self.displayed(null); + self.getMediaItems(pageCount); + }; + + self.toggleSelect = function(searchResult, force) { + var index = $.inArray(searchResult, self.selection()); + if (index == -1 || force) { + self.selection.remove(function(item) { return item.data.id == searchResult.data.id; }); + self.selection.push(searchResult); + searchResult.selected(true); + } else { + self.selection.remove(searchResult); + searchResult.selected(false); + } + + this.focus(searchResult); + }; + + self.select = function(searchResult) { + var index = $.inArray(searchResult, self.selection()); + if (index == -1) { + self.clearSelection(); + self.selection([searchResult]); + searchResult.selected(true); + } + + this.focus(searchResult); + }; + + self.scrolled = function(data, event) { + var elem = event.target; + if (elem.scrollTop > (elem.scrollHeight - elem.offsetHeight - 300)) { + self.getMediaItems(pageCount, true); + } + }; + + self.importMedia = function() { + var url = settings.importActionUrl + '?folderPath=' + encodeURIComponent(self.displayed()); + window.location = url; + }; + + var selectFolderOrRecent = function () { + if (self.displayed()) { + self.selectFolder(self.displayed()); + } else { + self.selectRecent(); + } + }; + self.orderMedia.subscribe(selectFolderOrRecent); self.mediaType.subscribe(selectFolderOrRecent); - } - - var viewModel = new mediaIndexViewModel(); - + } + + var viewModel = new mediaIndexViewModel(); + function mediaFolderViewModel(data) { var self = this; @@ -420,20 +420,20 @@ $(function () { var childTitles = $(elements).find(".media-library-folder-title"); attachFolderTitleDropEvent(childTitles); }; - } - + } + $.map(settings.childFolders, function (childFolder, index) { viewModel.mediaFolders.push(new mediaFolderViewModel(childFolder)); - }); - - enhanceViewModel(viewModel); - - ko.applyBindings(viewModel); - - if (settings.hasFolderPath) { - viewModel.displayFolder(settings.folderPath); - - //fetch displayed folder structure + }); + + enhanceViewModel(viewModel); + + ko.applyBindings(viewModel); + + if (settings.hasFolderPath) { + viewModel.displayFolder(settings.folderPath); + + //fetch displayed folder structure (function (displayedFolder) { var folders = viewModel.mediaFolders(); for (var x = 0; x < folders.length; x++) { @@ -444,125 +444,125 @@ $(function () { break; } } - })(settings.folderPath); - - History.pushState({ - action: 'displayFolder', - folderPath: settings.folderPath - }, '', '?folderPath=' + settings.folderPath); - } else { - viewModel.selectRecent(); - History.pushState({ action: 'selectRecent' }, '', '?recent'); - } - - window.onpopstate = function(event) { - if (event && event.state && event.state.action == 'displayFolder') { - viewModel.displayFolder(event.state.folder); - } - - if (event && event.state && event.state.action == 'selectRecent') { - viewModel.selectRecent(); - } - }; - - $("#media-library-main-list").on("mousedown", "li", function(e) { - // only for left click - if (e.which != 1) { - return; + })(settings.folderPath); + + History.pushState({ + action: 'displayFolder', + folderPath: settings.folderPath + }, '', '?folderPath=' + settings.folderPath); + } else { + viewModel.selectRecent(); + History.pushState({ action: 'selectRecent' }, '', '?recent'); + } + + window.onpopstate = function(event) { + if (event && event.state && event.state.action == 'displayFolder') { + viewModel.displayFolder(event.state.folder); } - - var searchResult = ko.dataFor(this); - if (e.ctrlKey) { - viewModel.toggleSelect(searchResult); - } else { - viewModel.select(searchResult); - } - }).on("contextmenu", "li", function() { - var searchResult = ko.dataFor(this); - viewModel.toggleSelect(searchResult); - return false; - }); - - $("#media-library-main-selection-select > .button-select").on('click', function() { - if (parent.$.colorbox) { - var selectedData = []; - for (var i = 0; i < viewModel.selection().length; i++) { - var selection = viewModel.selection()[i]; - selectedData.push(selection.data); - } - parent.$.colorbox.selectedData = selectedData; - parent.$.colorbox.close(); - } - ; - }); - - $("#media-library-main-selection-select > .button-cancel").on('click', function() { - if (parent.$.colorbox) { - parent.$.colorbox.selectedData = null; - parent.$.colorbox.close(); - } - ; + + if (event && event.state && event.state.action == 'selectRecent') { + viewModel.selectRecent(); + } + }; + + $("#media-library-main-list").on("mousedown", "li", function(e) { + // only for left click + if (e.which != 1) { + return; + } + + var searchResult = ko.dataFor(this); + if (e.ctrlKey) { + viewModel.toggleSelect(searchResult); + } else { + viewModel.select(searchResult); + } + }).on("contextmenu", "li", function() { + var searchResult = ko.dataFor(this); + viewModel.toggleSelect(searchResult); + return false; }); - $("#media-library-main-list").on("mouseover", ".media-thumbnail", function() { - if (!$(this).hasClass("ui-draggable")) { - $(this).draggable({ - revert: 'invalid', - //containment: 'li', - helper: function(event) { - var clone = $(event.currentTarget).clone().removeAttr('id'); - clone.removeClass('selected'); - clone.addClass('dragged-selection'); - - if (viewModel.selection().length > 1) { - clone.append($('

    ' + viewModel.selection().length + '

    ')); - } - - return clone; - - }, - cursor: 'move', - distance: 10, - appendTo: 'body', - create: function() { - // position the handler a little left to the center to let the number of selected items to appear - $(this).draggable("option", "cursorAt", { left: $(this).width() / 2 - 20, top: $(this).height() / 2 }); - } - }); - } - }); - - $('#delete-selection-button').click(function() { - if (!confirm(settings.deleteConfirmationMessage)) { - return false; - } - - var ids = []; - viewModel.selection().forEach(function(item) { ids.push(item.data.id); }); - var url = settings.deleteActionUrl; - - $.ajax({ - type: "POST", - url: url, - dataType: "json", - traditional: true, - data: { - mediaItemIds: ids, - __RequestVerificationToken: settings.antiForgeryToken - } - }).done(function(result) { - if (result) { - viewModel.results.remove(function(item) { - return ids.indexOf(item.data.id) != -1; - }); - - viewModel.clearSelection(); - } else { - console.log('failed to delete media items'); - } - return false; - }); - return false; - }); - })(window.mediaLibrarySettings); -}) + $("#media-library-main-selection-select > .button-select").on('click', function() { + if (parent.$.colorbox) { + var selectedData = []; + for (var i = 0; i < viewModel.selection().length; i++) { + var selection = viewModel.selection()[i]; + selectedData.push(selection.data); + } + parent.$.colorbox.selectedData = selectedData; + parent.$.colorbox.close(); + } + ; + }); + + $("#media-library-main-selection-select > .button-cancel").on('click', function() { + if (parent.$.colorbox) { + parent.$.colorbox.selectedData = null; + parent.$.colorbox.close(); + } + ; + }); + + $("#media-library-main-list").on("mouseover", ".media-thumbnail", function() { + if (!$(this).hasClass("ui-draggable")) { + $(this).draggable({ + revert: 'invalid', + //containment: 'li', + helper: function(event) { + var clone = $(event.currentTarget).clone().removeAttr('id'); + clone.removeClass('selected'); + clone.addClass('dragged-selection'); + + if (viewModel.selection().length > 1) { + clone.append($('

    ' + viewModel.selection().length + '

    ')); + } + + return clone; + + }, + cursor: 'move', + distance: 10, + appendTo: 'body', + create: function() { + // position the handler a little left to the center to let the number of selected items to appear + $(this).draggable("option", "cursorAt", { left: $(this).width() / 2 - 20, top: $(this).height() / 2 }); + } + }); + } + }); + + $('#delete-selection-button').click(function() { + if (!confirm(settings.deleteConfirmationMessage)) { + return false; + } + + var ids = []; + viewModel.selection().forEach(function(item) { ids.push(item.data.id); }); + var url = settings.deleteActionUrl; + + $.ajax({ + type: "POST", + url: url, + dataType: "json", + traditional: true, + data: { + mediaItemIds: ids, + __RequestVerificationToken: settings.antiForgeryToken + } + }).done(function(result) { + if (result) { + viewModel.results.remove(function(item) { + return ids.indexOf(item.data.id) != -1; + }); + + viewModel.clearSelection(); + } else { + console.log('failed to delete media items'); + } + return false; + }); + return false; + }); + })(window.mediaLibrarySettings); +}) From 5a633330eba6644e24d2b6a18f15305fd8798338 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 17:17:32 -0700 Subject: [PATCH 108/116] Adding PromptOnNavigate option. --- .../Scripts/media-library-picker.js | 33 ++++++++++--------- .../Fields/MediaLibraryPicker.Edit.cshtml | 3 +- .../Views/MediaLibraryPicker.cshtml | 6 ++-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js index e451a07bd..27110b0c0 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js @@ -10,6 +10,7 @@ var pipe = element.data("pipe"); var returnUrl = element.data("return-url"); var addUrl = element.data("add-url"); + var promptOnNavigate = element.data("prompt-on-navigate"); var addButton = element.find(".button.add"); var template = '
  • {thumbnail}

    {title}

    ' + removeText + '' + pipe + '' + editText + '
  • '; @@ -30,21 +31,23 @@ addButton.show(); } }; - - window.mediaLibraryDirty = false; - var showSaveMsg = function() { - element.find('.media-library-picker-message').show(); - window.mediaLibraryDirty = true; - }; - if (!window.mediaLibraryNavigateAway) { - $(window).on("beforeunload", window.mediaLibraryNavigateAway = function() { - if (window.mediaLibraryDirty) { - return dirtyText; - } - }); - element.closest("form").on("submit", function() { - window.mediaLibraryDirty = false; - }); + + if (promptOnNavigate) { + window.mediaLibraryDirty = false; + var showSaveMsg = function() { + element.find('.media-library-picker-message').show(); + window.mediaLibraryDirty = true; + }; + if (!window.mediaLibraryNavigateAway) { + $(window).on("beforeunload", window.mediaLibraryNavigateAway = function() { + if (window.mediaLibraryDirty) { + return dirtyText; + } + }); + element.closest("form").on("submit", function() { + window.mediaLibraryDirty = false; + }); + } } refreshIds(); diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml index 33ecc2ecd..e7ff51031 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml @@ -9,4 +9,5 @@ Multiple: settings.Multiple, Required: settings.Required, Hint: settings.Hint, - ContentItems: Model.ContentItems) \ No newline at end of file + ContentItems: Model.ContentItems, + PromptOnNavigate: true) \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml index b5a7bb466..d5dc16ee5 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml @@ -13,6 +13,7 @@ var multiple = (bool)(Model.Multiple ?? false); var required = (bool)(Model.Required ?? false); var hint = (string) Model.Hint; + var promptOnNavigate = (bool) (Model.PromptOnNavigate ?? true); var contentItems = (IEnumerable)Model.ContentItems ?? Enumerable.Empty(); var contentManager = WorkContext.Resolve(); } @@ -25,8 +26,9 @@ data-dirty-text="@T("You have unsaved changes. Please only accept to leave if you don't mind losing those changes.")" data-pipe="@T(" | ")" data-add-url="@HttpUtility.JavaScriptStringEncode(Url.Action("Index", "Admin", new { area = "Orchard.MediaLibrary", dialog = true }))" - data-return-url="@HttpUtility.JavaScriptStringEncode(Request.RawUrl)"> - + data-return-url="@HttpUtility.JavaScriptStringEncode(Request.RawUrl)" + data-prompt-on-navigate="@promptOnNavigate.ToString().ToLower()"> +
    @T("You need to save your changes.")
      From 658aa8384db97e3aaf1e889876158d9dd10bcf8d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 17:58:31 -0700 Subject: [PATCH 109/116] Bugfixing. The "showSaveMsg" function needs to be there regardless of the "promptOnNavigate" value. --- .../Scripts/media-library-picker.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js index 27110b0c0..3af7a7e9b 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js @@ -32,12 +32,14 @@ } }; - if (promptOnNavigate) { - window.mediaLibraryDirty = false; - var showSaveMsg = function() { - element.find('.media-library-picker-message').show(); - window.mediaLibraryDirty = true; - }; + var showSaveMsg = function () { + element.find('.media-library-picker-message').show(); + window.mediaLibraryDirty = true; + }; + + window.mediaLibraryDirty = false; + + if (promptOnNavigate) { if (!window.mediaLibraryNavigateAway) { $(window).on("beforeunload", window.mediaLibraryNavigateAway = function() { if (window.mediaLibraryDirty) { From e50c2e1d398d7850f3442343d5d304fded02117e Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 18:13:28 -0700 Subject: [PATCH 110/116] Adding ShowSaveWarning option. --- .../Orchard.MediaLibrary/Scripts/media-library-picker.js | 4 ++++ .../EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml | 3 ++- .../Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js index 3af7a7e9b..d98a34979 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library-picker.js @@ -11,6 +11,7 @@ var returnUrl = element.data("return-url"); var addUrl = element.data("add-url"); var promptOnNavigate = element.data("prompt-on-navigate"); + var showSaveWarning = element.data("show-save-warning"); var addButton = element.find(".button.add"); var template = '
    • {thumbnail}

      {title}

      ' + removeText + '' + pipe + '' + editText + '
    • '; @@ -33,6 +34,9 @@ }; var showSaveMsg = function () { + if (!showSaveWarning) + return; + element.find('.media-library-picker-message').show(); window.mediaLibraryDirty = true; }; diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml index e7ff51031..9a0f21f4d 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/EditorTemplates/Fields/MediaLibraryPicker.Edit.cshtml @@ -10,4 +10,5 @@ Required: settings.Required, Hint: settings.Hint, ContentItems: Model.ContentItems, - PromptOnNavigate: true) \ No newline at end of file + PromptOnNavigate: true, + ShowSaveWarning: true) \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml index d5dc16ee5..f4927c98c 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/MediaLibraryPicker.cshtml @@ -14,6 +14,7 @@ var required = (bool)(Model.Required ?? false); var hint = (string) Model.Hint; var promptOnNavigate = (bool) (Model.PromptOnNavigate ?? true); + var showSaveWarning = (bool)(Model.ShowSaveWarning); var contentItems = (IEnumerable)Model.ContentItems ?? Enumerable.Empty(); var contentManager = WorkContext.Resolve(); } @@ -27,7 +28,8 @@ data-pipe="@T(" | ")" data-add-url="@HttpUtility.JavaScriptStringEncode(Url.Action("Index", "Admin", new { area = "Orchard.MediaLibrary", dialog = true }))" data-return-url="@HttpUtility.JavaScriptStringEncode(Request.RawUrl)" - data-prompt-on-navigate="@promptOnNavigate.ToString().ToLower()"> + data-prompt-on-navigate="@promptOnNavigate.ToString().ToLower()" + data-show-save-warning="@showSaveWarning.ToString().ToLower()">
      @T("You need to save your changes.")
      From 02441b25209c4cb4e1d6e3833b0a50fe65aa2580 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Jul 2014 19:12:51 -0700 Subject: [PATCH 111/116] Making content item titles, content types and content parts clickable. --- .../Orchard.AuditTrail/Helpers/HtmlExtensions.cs | 15 +++++++++++++++ .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 1 + .../AuditTrailEvent-Content.SummaryAdmin.cshtml | 8 +------- .../Views/AuditTrailEvent-Content.cshtml | 2 +- .../AuditTrailEvent-ContentPart-Created.cshtml | 2 +- ...ailEvent-ContentPart-DescriptionChanged.cshtml | 2 +- .../AuditTrailEvent-ContentPart-FieldAdded.cshtml | 2 +- ...uditTrailEvent-ContentPart-FieldRemoved.cshtml | 2 +- ...tPart-FieldSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...lEvent-ContentPart-FieldSettingsUpdated.cshtml | 2 +- ...ntPart-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ilEvent-ContentPart-PartSettingsUpdated.cshtml | 2 +- .../AuditTrailEvent-ContentType-Created.cshtml | 2 +- ...tType-FieldSettingsUpdated.SummaryAdmin.cshtml | 4 ++-- ...lEvent-ContentType-FieldSettingsUpdated.cshtml | 4 ++-- .../AuditTrailEvent-ContentType-PartAdded.cshtml | 2 +- ...AuditTrailEvent-ContentType-PartRemoved.cshtml | 2 +- ...ntType-PartSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ilEvent-ContentType-PartSettingsUpdated.cshtml | 2 +- ...vent-ContentType-TypeDisplayNameUpdated.cshtml | 2 +- ...ntType-TypeSettingsUpdated.SummaryAdmin.cshtml | 2 +- ...ilEvent-ContentType-TypeSettingsUpdated.cshtml | 2 +- 22 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/HtmlExtensions.cs diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/HtmlExtensions.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/HtmlExtensions.cs new file mode 100644 index 000000000..0ea705cb7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Helpers/HtmlExtensions.cs @@ -0,0 +1,15 @@ +using System.Web; +using System.Web.Mvc; +using System.Web.Mvc.Html; + +namespace Orchard.AuditTrail.Helpers { + public static class HtmlExtensions { + public static IHtmlString ContentPartEditLink(this HtmlHelper html, string contentPartName) { + return html.ActionLink(contentPartName, "EditPart", "Admin", new {id = contentPartName, area = "Orchard.ContentTypes"}, null); + } + + public static IHtmlString ContentTypeEditLink(this HtmlHelper html, string contentTypeName) { + return html.ActionLink(contentTypeName, "Edit", "Admin", new { id = contentTypeName, area = "Orchard.ContentTypes" }, null); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 5eb95f6bc..6e8555c31 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -182,6 +182,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index 5409189e8..93bdb3549 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -7,17 +7,11 @@ var eventVersionNumber = eventData.Get("VersionNumber"); var eventIsPublished = eventData.Get("Published"); var contentType = contentItem.ContentType; - var title = Html.ItemDisplayText(contentItem); - var isLatest = contentItem.VersionRecord.Number == eventVersionNumber; }
      - @T("{0} - {1} (version {2})", contentType, title, eventVersionNumber) + @T("{0} - {1} (version {2})", contentType, Html.ItemEditLink(contentItem), eventVersionNumber) @if (eventIsPublished) { @T(" - ") @T("View") } - else if (isLatest) { - @T(" - ") - @T("Edit") - }
      \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index 1511c5238..e8c6a8974 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -13,7 +13,7 @@ }
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml index fc1c8ff5b..3860fdefe 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.SummaryAdmin.cshtml @@ -9,7 +9,7 @@ var diff = (DiffDictionary)Model.Diff; }
    - @T("Settings for the content part {0} were changed:", contentPartName) + @T("Settings for the content part {0} were changed:", Html.ContentPartEditLink(contentPartName))
      @foreach (var setting in diff) {
    • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml index 8f549c89a..a3cceb3eb 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentPart-PartSettingsUpdated.cshtml @@ -9,7 +9,7 @@ var diff = (DiffDictionary)Model.Diff; }
      - @T("Settings for the content part {0} were changed:", contentPartName) + @T("Settings for the content part {0} were changed:", Html.ContentPartEditLink(contentPartName))
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml index 4354b6a7e..aa32ed1cd 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-Created.cshtml @@ -5,5 +5,5 @@ var contentTypeDisplayName = eventData.Get("ContentTypeDisplayName"); }
    - @T("The content type {0} was created.", contentTypeName) + @T("The content type {0} was created.", Html.ContentTypeEditLink(contentTypeName))
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml index 2056b2a7e..a1d721d5e 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.SummaryAdmin.cshtml @@ -10,10 +10,10 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; }
    - @T(captionTemplate, contentFieldName, contentPartName, contentTypeName) + @T(captionTemplate, contentFieldName, Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
      @foreach (var setting in diff) {
    • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml index ecae29265..4d38a971d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-FieldSettingsUpdated.cshtml @@ -10,10 +10,10 @@ var contentFieldName = eventData.Get("ContentFieldName"); var diff = (DiffDictionary)Model.Diff; var isImplicitPart = contentTypeName == contentPartName; - var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; + var captionTemplate = isImplicitPart ? "Settings for the field {0} attached to the content type {1} were updated:" : "Settings for the field {0} attached to content part {1} of the content type {2} were updated:"; }
      - @T(captionTemplate, contentFieldName, contentPartName, contentTypeName) + @T(captionTemplate, contentFieldName, Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml index cab906c38..d6cb14793 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartAdded.cshtml @@ -5,5 +5,5 @@ var contentPartName = eventData.Get("ContentPartName"); }
    - @T("The content part {0} was added to the content type {1}.", contentPartName, contentTypeName) + @T("The content part {0} was added to the content type {1}.", Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml index a92b075d5..5dd6a24ea 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartRemoved.cshtml @@ -5,5 +5,5 @@ var contentPartName = eventData.Get("ContentPartName"); }
    - @T("The content part {0} was removed from the content type {1}.", contentPartName, contentTypeName) + @T("The content part {0} was removed from the content type {1}.", Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml index 0b6ba8139..59e4a9f17 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.SummaryAdmin.cshtml @@ -10,7 +10,7 @@ var diff = (DiffDictionary)Model.Diff; }
    - @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName) + @T("Settings for the content part {0} attached to the content type {1} were changed:", Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
      @foreach (var setting in diff) {
    • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml index 7105743e1..6f2bd260a 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-PartSettingsUpdated.cshtml @@ -10,7 +10,7 @@ var diff = (DiffDictionary)Model.Diff; }
      - @T("Settings for the content part {0} attached to the content type {1} were changed:", contentPartName, contentTypeName) + @T("Settings for the content part {0} attached to the content type {1} were changed:", Html.ContentPartEditLink(contentPartName), Html.ContentTypeEditLink(contentTypeName))
    diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml index 02d942e9a..f72a26f2d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeDisplayNameUpdated.cshtml @@ -6,5 +6,5 @@ var newDisplayName = eventData.Get("NewDisplayName"); }
    - @T("The display name for the content type {0} was changed from {1} to {2}.", contentTypeName, oldDisplayName.OrIfEmpty(T("[Empty]")), newDisplayName.OrIfEmpty(T("[Empty]"))) + @T("The display name for the content type {0} was changed from {1} to {2}.", Html.ContentTypeEditLink(contentTypeName), oldDisplayName.OrIfEmpty(T("[Empty]")), newDisplayName.OrIfEmpty(T("[Empty]")))
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml index 463c37186..4ec9f7610 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.SummaryAdmin.cshtml @@ -9,7 +9,7 @@ var diff = (DiffDictionary) Model.Diff; }
    - @T("Settings for the content type {0} were changed:", contentTypeName) + @T("Settings for the content type {0} were changed:", Html.ContentTypeEditLink(contentTypeName))
      @foreach (var setting in diff) {
    • diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml index 56729adfa..603249d2d 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-ContentType-TypeSettingsUpdated.cshtml @@ -9,7 +9,7 @@ var diff = (DiffDictionary) Model.Diff; }
      - @T("Settings for the content type {0} were changed:", contentTypeName) + @T("Settings for the content type {0} were changed:", Html.ContentTypeEditLink(contentTypeName))
    From 4466e889247980d5d00f9798f601c54a1332203f Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Tue, 29 Jul 2014 15:38:44 +0200 Subject: [PATCH 112/116] Fixed whitespace handling in audit trail table display. --- .../Styles/audittrail-display.css | 7 +++++ .../Views/Admin/Index.cshtml | 28 ++++++++--------- .../Views/Parts.AuditTrail.cshtml | 31 ++++++++++--------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css index 82253eb60..e6d589daa 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-display.css @@ -33,3 +33,10 @@ .audittrail-event-metadata-section strong { /*font-weight: bold;*/ } + +.audittrail-list-section table .category-column, +.audittrail-list-section table .event-column, +.audittrail-list-section table .user-column, +.audittrail-list-section table .timestamp-column { + white-space: nowrap; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml index a9769f103..6819294d3 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Admin/Index.cshtml @@ -34,25 +34,25 @@
    - - - - - - - + + + + + + + @foreach (var record in Model.Records) { - - - - - - - + + + + + + + } diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml index 52aa592dc..3eb6d6662 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/Parts.AuditTrail.cshtml @@ -1,6 +1,7 @@ @using Orchard.AuditTrail.Models @using Orchard.AuditTrail.ViewModels @{ + Style.Include("audittrail-display.css"); Style.Include("audittrail-part.css"); Script.Require("ShapesBase"); Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot(); @@ -21,25 +22,25 @@
    @T("Category")@T("Event")@T("User")@T("Timestamp")@T("Summary")@T("Comment")@T("Category")@T("Event")@T("User")@T("Timestamp")@T("Summary")@T("Comment")
    @record.CategoryDescriptor.Name@record.EventDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@Display(record.SummaryShape)@record.Record.Comment@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)@record.CategoryDescriptor.Name@record.EventDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@Display(record.SummaryShape)@record.Record.Comment@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)
    - - - - - - - + + + + + + + - @foreach (var record in records) { + @foreach (var record in Model.Records) { - - - - - - - + + + + + + + } From 51dc062e0434c4db275e761a97b3cfc67ee079a6 Mon Sep 17 00:00:00 2001 From: Daniel Stolt Date: Tue, 29 Jul 2014 15:44:06 +0200 Subject: [PATCH 113/116] Fixing styling of text in admin theme, making it visible on Chrome. --- src/Orchard.Web/Themes/TheAdmin/Styles/site.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css index 7d49fc0b1..3d86408f6 100644 --- a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css +++ b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css @@ -143,7 +143,7 @@ h4 img, h5 img, h6 img { margin: 0; } -strong {font-weight:600;} +strong {font-weight:bold;} .smallText {font-size:1em; line-height:1.4em;} hr {border:0; height:1px; color:#e4e5e6; background-color:#e4e5e6;} From 6605eeb34dc1ac856a68f14ef3744e58b680334c Mon Sep 17 00:00:00 2001 From: Piotr Szmyd Date: Tue, 29 Jul 2014 16:06:31 +0200 Subject: [PATCH 114/116] #20839: Fixing issue with tabs in Dashboard not appearing after recent nav changes. They show up again. Work Item: 20839 --- src/Orchard/UI/Navigation/NavigationHelper.cs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Orchard/UI/Navigation/NavigationHelper.cs b/src/Orchard/UI/Navigation/NavigationHelper.cs index 880742e53..7b028d9ce 100644 --- a/src/Orchard/UI/Navigation/NavigationHelper.cs +++ b/src/Orchard/UI/Navigation/NavigationHelper.cs @@ -80,11 +80,24 @@ namespace Orchard.UI.Navigation { /// The current route data. /// A stack with the selection path being the last node the currently selected one. public static Stack SetSelectedPath(IEnumerable menuItems, HttpRequestBase currentRequest, RouteValueDictionary currentRouteData) { - if (menuItems == null) - return null; + // doing route data comparison first and if that fails, fallback to string-based URL lookup + var path = SetSelectedPath(menuItems, currentRequest, currentRouteData, false) + ?? SetSelectedPath(menuItems, currentRequest, currentRouteData, true); + return path; + } + + /// + /// Identifies the currently selected path, starting from the selected node. + /// + /// All the menuitems in the navigation menu. + /// The currently executed request if any + /// The current route data. + /// Should compare raw string URLs instead of route data. + /// A stack with the selection path being the last node the currently selected one. + private static Stack SetSelectedPath(IEnumerable menuItems, HttpRequestBase currentRequest, RouteValueDictionary currentRouteData, bool compareUrls) { foreach (MenuItem menuItem in menuItems) { - Stack selectedPath = SetSelectedPath(menuItem.Items, currentRequest, currentRouteData); + Stack selectedPath = SetSelectedPath(menuItem.Items, currentRequest, currentRouteData, compareUrls); if (selectedPath != null) { menuItem.Selected = true; selectedPath.Push(menuItem); @@ -92,10 +105,11 @@ namespace Orchard.UI.Navigation { } // compare route values (if any) first - bool match = menuItem.RouteValues != null && RouteMatches(menuItem.RouteValues, currentRouteData); + // if URL string comparison is used it means all previous route matches failed, thus no need to do them twice + bool match = !compareUrls && menuItem.RouteValues != null && RouteMatches(menuItem.RouteValues, currentRouteData); - // if route match failed, try comparing URL strings - if (currentRequest != null && !match) { + // if route match failed, try comparing URL strings, if + if (currentRequest != null && !match && compareUrls) { string appPath = currentRequest.ApplicationPath ?? "/"; string requestUrl = currentRequest.Path.StartsWith(appPath) ? currentRequest.Path.Substring(appPath.Length) : currentRequest.Path; From dff819ae04d09e63ca302bdeccc74711633f1c61 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 29 Jul 2014 17:22:11 -0700 Subject: [PATCH 115/116] Improving content event presentation. --- .../Orchard.AuditTrail/Orchard.AuditTrail.csproj | 1 + .../Styles/audittrail-content-event.css | 3 +++ .../AuditTrailEvent-Content.SummaryAdmin.cshtml | 13 +++++++++---- .../Views/AuditTrailEvent-Content.cshtml | 7 +++++-- 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-content-event.css diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj index 6e8555c31..0d8dd7d4b 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Orchard.AuditTrail.csproj @@ -81,6 +81,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-content-event.css b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-content-event.css new file mode 100644 index 000000000..e560ab35c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Styles/audittrail-content-event.css @@ -0,0 +1,3 @@ +.audittrail-content-eventmetadata { + margin-bottom: 1em; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml index 93bdb3549..f94e25ae1 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.SummaryAdmin.cshtml @@ -1,17 +1,22 @@ @using Orchard.AuditTrail.Helpers +@using Orchard.AuditTrail.Services.Models @using Orchard.ContentManagement @{ + var descriptor = (AuditTrailEventDescriptor)Model.Descriptor; var eventData = (IDictionary) Model.EventData; var contentItem = (ContentItem) Model.ContentItem; var contentItemId = contentItem.Id; var eventVersionNumber = eventData.Get("VersionNumber"); var eventIsPublished = eventData.Get("Published"); var contentType = contentItem.ContentType; + var isLatest = contentItem.VersionRecord.Number == eventVersionNumber; }
    - @T("{0} - {1} (version {2})", contentType, Html.ItemEditLink(contentItem), eventVersionNumber) - @if (eventIsPublished) { - @T(" - ") - @T("View") + @if (eventIsPublished || isLatest) { + @T("{2} of the {0} {1} was {3}.", contentType.ToLower(), Html.ItemEditLink(contentItem), Html.ActionLink(T("Version {0}", eventVersionNumber).Text, "Detail", "Content", new { area = "Orchard.AuditTrail", id = contentItemId, version = eventVersionNumber }, null), descriptor.Name.Text.ToLower()) + } + else { + @T("{0} - {1}", contentType, Html.ItemEditLink(contentItem)) + }
    \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml index e8c6a8974..433297470 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Views/AuditTrailEvent-Content.cshtml @@ -1,6 +1,9 @@ @using Orchard.AuditTrail.Models @using Orchard.AuditTrail.Providers.Content @using Orchard.ContentManagement +@{ + Style.Include("audittrail-content-event.css"); +} @{ var record = (AuditTrailEventRecord)Model.Record; var contentItem = (ContentItem)Model.ContentItem; @@ -13,8 +16,8 @@ }
    @T("Category")@T("Event")@T("User")@T("Timestamp")@T("Summary")@T("Comment")@T("Category")@T("Event")@T("User")@T("Timestamp")@T("Summary")@T("Comment")
    @record.CategoryDescriptor.Name@record.EventDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@Display(record.SummaryShape)@record.Record.Comment@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)@record.CategoryDescriptor.Name@record.EventDescriptor.Name@record.Record.UserName@Display.DateTime(DateTimeUtc: record.Record.CreatedUtc, CustomFormat: T("g"))@Display(record.SummaryShape)@record.Record.Comment@Html.ActionLink(T("Details").Text, "Detail", "Admin", new { id = record.Record.Id, area = "Orchard.AuditTrail" }, null)