diff --git a/src/Orchard.Tests/Commands/CommandHandlerDescriptorBuilderTests.cs b/src/Orchard.Tests/Commands/CommandHandlerDescriptorBuilderTests.cs index 234e787fa..2de1b3c75 100644 --- a/src/Orchard.Tests/Commands/CommandHandlerDescriptorBuilderTests.cs +++ b/src/Orchard.Tests/Commands/CommandHandlerDescriptorBuilderTests.cs @@ -45,11 +45,13 @@ namespace Orchard.Tests.Commands { var builder = new CommandHandlerDescriptorBuilder(); var descriptor = builder.Build(typeof(PublicMethodsOnly)); Assert.That(descriptor, Is.Not.Null); - Assert.That(descriptor.Commands.Count(), Is.EqualTo(3)); + Assert.That(descriptor.Commands.Count(), Is.EqualTo(1)); Assert.That(descriptor.Commands.Single(d => d.Name == "Method"), Is.Not.Null); } +#pragma warning disable 660,661 public class PublicMethodsOnly { +#pragma warning restore 660,661 public bool Bar { get; set; } // no accessors public bool Field = true; // no field @@ -70,14 +72,6 @@ namespace Orchard.Tests.Commands { return false; } - public override int GetHashCode() { - throw new NotImplementedException(); - } - - public override bool Equals(Object obj) { - throw new NotImplementedException(); - } - public void Method() { } } diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Drivers/ArchiveLaterPartDriver.cs b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Drivers/ArchiveLaterPartDriver.cs index 1df330455..538b8982e 100644 --- a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Drivers/ArchiveLaterPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Drivers/ArchiveLaterPartDriver.cs @@ -1,24 +1,19 @@ using System; -using Orchard; using Orchard.ArchiveLater.Models; using Orchard.ArchiveLater.Services; using Orchard.ArchiveLater.ViewModels; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; -using Orchard.Core.Common.Services; using Orchard.Localization; -namespace ArchiveLater.Drivers { +namespace Orchard.ArchiveLater.Drivers { public class ArchiveLaterPartDriver : ContentPartDriver { - private const string TemplatePrefix = "ArchiveLater"; - private readonly ICommonService _commonService; + private const string TemplateName = "Parts/ArchiveLater"; private readonly IArchiveLaterService _archiveLaterService; public ArchiveLaterPartDriver( IOrchardServices services, - ICommonService commonService, IArchiveLaterService archiveLaterService) { - _commonService = commonService; _archiveLaterService = archiveLaterService; T = NullLocalizer.Instance; Services = services; @@ -27,6 +22,8 @@ namespace ArchiveLater.Drivers { public Localizer T { get; set; } public IOrchardServices Services { get; set; } + protected override string Prefix { get { return "ArchiveLater"; } } + protected override DriverResult Display(ArchiveLaterPart part, string displayType, dynamic shapeHelper) { return ContentShape("Parts_ArchiveLater_Metadata_SummaryAdmin", shape => { @@ -40,20 +37,24 @@ namespace ArchiveLater.Drivers { } protected override DriverResult Editor(ArchiveLaterPart part, dynamic shapeHelper) { - return ArchiveEditor(part, null, shapeHelper); - } - - protected override DriverResult Editor(ArchiveLaterPart instance, IUpdateModel updater, dynamic shapeHelper) { - return ArchiveEditor(instance, updater, shapeHelper); - } - - DriverResult ArchiveEditor(ArchiveLaterPart part, IUpdateModel updater, dynamic shapeHelper) { var model = new ArchiveLaterViewModel(part); - if ( updater != null && updater.TryUpdateModel(model, TemplatePrefix, null, null) ) { - if (model.ArchiveLater) { + model.ScheduledArchiveUtc = part.ScheduledArchiveUtc.Value; + model.ArchiveLater = model.ScheduledArchiveUtc.HasValue; + model.ScheduledArchiveDate = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToShortDateString() : String.Empty; + model.ScheduledArchiveTime = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToShortTimeString() : String.Empty; + + return ContentShape("Parts_ArchiveLater_Edit", + () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); + } + + protected override DriverResult Editor(ArchiveLaterPart part, IUpdateModel updater, dynamic shapeHelper) { + var model = new ArchiveLaterViewModel(part); + + if (updater.TryUpdateModel(model, Prefix, null, null) ) { + if ( model.ArchiveLater ) { DateTime scheduled; - if (DateTime.TryParse(string.Format("{0} {1}", model.ScheduledArchiveDate, model.ScheduledArchiveTime), out scheduled)) + if ( DateTime.TryParse(string.Format("{0} {1}", model.ScheduledArchiveDate, model.ScheduledArchiveTime), out scheduled) ) model.ScheduledArchiveUtc = scheduled.ToUniversalTime(); _archiveLaterService.ArchiveLater(model.ContentItem, model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value : DateTime.MaxValue); } @@ -63,7 +64,7 @@ namespace ArchiveLater.Drivers { } return ContentShape("Parts_ArchiveLater_Edit", - () => shapeHelper.EditorTemplate(TemplateName: "Parts/ArchiveLater", Model: model, Prefix: Prefix)); + () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); } } } diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Module.txt b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Module.txt index 2c260dfe0..3de89aa81 100644 --- a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Module.txt @@ -9,4 +9,4 @@ Features: Orchard.ArchiveLater: Description: Scheduled archiving. Category: Content - Dependencies: Common, Settings + Dependencies: Common, Settings, Orchard.jQuery diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/EditorTemplates/Parts/ArchiveLater.cshtml b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/EditorTemplates/Parts/ArchiveLater.cshtml index 1d2c1b6a5..dade5a3b0 100644 --- a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/EditorTemplates/Parts/ArchiveLater.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/EditorTemplates/Parts/ArchiveLater.cshtml @@ -21,7 +21,10 @@ @Html.EditorFor(m => m.ScheduledArchiveTime) - \ No newline at end of file + $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveDate")').datepicker({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater")').attr("checked", "checked") }); + $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveTime")').timepickr().focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater")').attr("checked", "checked") }); + }) +//]]> + +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Modules.cshtml b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Modules.cshtml index cc1fc43c5..8a4d3068b 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Modules.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Modules.cshtml @@ -10,7 +10,7 @@ diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Themes.cshtml b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Themes.cshtml index 2f3257c25..ad1922be1 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Themes.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Themes.cshtml @@ -13,7 +13,7 @@ diff --git a/src/Orchard/Commands/CommandHostAgent.cs b/src/Orchard/Commands/CommandHostAgent.cs index 05799f2f1..ad19d8655 100644 --- a/src/Orchard/Commands/CommandHostAgent.cs +++ b/src/Orchard/Commands/CommandHostAgent.cs @@ -6,6 +6,7 @@ using System.Web.Mvc; using System.Web.Routing; using Autofac; using Orchard.Caching; +using Orchard.Data; using Orchard.Environment; using Orchard.Environment.Configuration; using Orchard.Environment.State; @@ -48,6 +49,8 @@ namespace Orchard.Commands { tenant = tenant ?? "Default"; using (var env = CreateStandaloneEnvironment(tenant)) { + var commandManager = env.Resolve(); + var transactionManager = env.Resolve(); var parameters = new CommandParameters { Arguments = args, @@ -56,7 +59,16 @@ namespace Orchard.Commands { Output = output }; - env.Resolve().Execute(parameters); + try { + commandManager.Execute(parameters); + } + catch { + // any database changes in this using(env) scope are invalidated + transactionManager.Cancel(); + + // exception handling performed below + throw; + } } // in effect "pump messages" see PostMessage circa 1980 diff --git a/src/Orchard/ContentManagement/Drivers/ContentPartDriver.cs b/src/Orchard/ContentManagement/Drivers/ContentPartDriver.cs index 146fce428..7506aa975 100644 --- a/src/Orchard/ContentManagement/Drivers/ContentPartDriver.cs +++ b/src/Orchard/ContentManagement/Drivers/ContentPartDriver.cs @@ -42,11 +42,11 @@ namespace Orchard.ContentManagement.Drivers { } public ContentShapeResult ContentShape(string shapeType, Func factory) { - return ContentShapeImplementation(shapeType, null, ctx=>factory(CreateShape(ctx, shapeType))); + return ContentShapeImplementation(shapeType, null, ctx => factory(CreateShape(ctx, shapeType))); } public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func factory) { - return ContentShapeImplementation(shapeType, defaultLocation, factory); + return ContentShapeImplementation(shapeType, defaultLocation, ctx => factory(CreateShape(ctx, shapeType))); } private ContentShapeResult ContentShapeImplementation(string shapeType, string defaultLocation, Func shapeBuilder) { diff --git a/src/Orchard/Tasks/SweepGenerator.cs b/src/Orchard/Tasks/SweepGenerator.cs index 627838b9a..bd1a25076 100644 --- a/src/Orchard/Tasks/SweepGenerator.cs +++ b/src/Orchard/Tasks/SweepGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Timers; using Autofac; +using Orchard.Data; using Orchard.Environment; using Orchard.Logging; @@ -57,9 +58,20 @@ namespace Orchard.Tasks { public void DoWork() { // makes an inner container, similar to the per-request container using (var scope = _workContextAccessor.CreateWorkContextScope()) { - // resolve the manager and invoke it - var manager = scope.Resolve(); - manager.Sweep(); + var transactionManager = scope.Resolve(); + + try { + // resolve the manager and invoke it + var manager = scope.Resolve(); + manager.Sweep(); + } + catch { + // any database changes in this using scope are invalidated + transactionManager.Cancel(); + + // pass exception along to actual handler + throw; + } } }