mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -45,11 +45,13 @@ namespace Orchard.Tests.Commands {
|
|||||||
var builder = new CommandHandlerDescriptorBuilder();
|
var builder = new CommandHandlerDescriptorBuilder();
|
||||||
var descriptor = builder.Build(typeof(PublicMethodsOnly));
|
var descriptor = builder.Build(typeof(PublicMethodsOnly));
|
||||||
Assert.That(descriptor, Is.Not.Null);
|
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);
|
Assert.That(descriptor.Commands.Single(d => d.Name == "Method"), Is.Not.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable 660,661
|
||||||
public class PublicMethodsOnly {
|
public class PublicMethodsOnly {
|
||||||
|
#pragma warning restore 660,661
|
||||||
public bool Bar { get; set; } // no accessors
|
public bool Bar { get; set; } // no accessors
|
||||||
public bool Field = true; // no field
|
public bool Field = true; // no field
|
||||||
|
|
||||||
@@ -70,14 +72,6 @@ namespace Orchard.Tests.Commands {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(Object obj) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Method() {
|
public void Method() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using Orchard;
|
|
||||||
using Orchard.ArchiveLater.Models;
|
using Orchard.ArchiveLater.Models;
|
||||||
using Orchard.ArchiveLater.Services;
|
using Orchard.ArchiveLater.Services;
|
||||||
using Orchard.ArchiveLater.ViewModels;
|
using Orchard.ArchiveLater.ViewModels;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Common.Services;
|
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace ArchiveLater.Drivers {
|
namespace Orchard.ArchiveLater.Drivers {
|
||||||
public class ArchiveLaterPartDriver : ContentPartDriver<ArchiveLaterPart> {
|
public class ArchiveLaterPartDriver : ContentPartDriver<ArchiveLaterPart> {
|
||||||
private const string TemplatePrefix = "ArchiveLater";
|
private const string TemplateName = "Parts/ArchiveLater";
|
||||||
private readonly ICommonService _commonService;
|
|
||||||
private readonly IArchiveLaterService _archiveLaterService;
|
private readonly IArchiveLaterService _archiveLaterService;
|
||||||
|
|
||||||
public ArchiveLaterPartDriver(
|
public ArchiveLaterPartDriver(
|
||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
ICommonService commonService,
|
|
||||||
IArchiveLaterService archiveLaterService) {
|
IArchiveLaterService archiveLaterService) {
|
||||||
_commonService = commonService;
|
|
||||||
_archiveLaterService = archiveLaterService;
|
_archiveLaterService = archiveLaterService;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Services = services;
|
Services = services;
|
||||||
@@ -27,6 +22,8 @@ namespace ArchiveLater.Drivers {
|
|||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
public IOrchardServices Services { get; set; }
|
public IOrchardServices Services { get; set; }
|
||||||
|
|
||||||
|
protected override string Prefix { get { return "ArchiveLater"; } }
|
||||||
|
|
||||||
protected override DriverResult Display(ArchiveLaterPart part, string displayType, dynamic shapeHelper) {
|
protected override DriverResult Display(ArchiveLaterPart part, string displayType, dynamic shapeHelper) {
|
||||||
return ContentShape("Parts_ArchiveLater_Metadata_SummaryAdmin",
|
return ContentShape("Parts_ArchiveLater_Metadata_SummaryAdmin",
|
||||||
shape => {
|
shape => {
|
||||||
@@ -40,20 +37,24 @@ namespace ArchiveLater.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(ArchiveLaterPart part, dynamic shapeHelper) {
|
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);
|
var model = new ArchiveLaterViewModel(part);
|
||||||
|
|
||||||
if ( updater != null && updater.TryUpdateModel(model, TemplatePrefix, null, null) ) {
|
model.ScheduledArchiveUtc = part.ScheduledArchiveUtc.Value;
|
||||||
if (model.ArchiveLater) {
|
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;
|
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();
|
model.ScheduledArchiveUtc = scheduled.ToUniversalTime();
|
||||||
_archiveLaterService.ArchiveLater(model.ContentItem, model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value : DateTime.MaxValue);
|
_archiveLaterService.ArchiveLater(model.ContentItem, model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value : DateTime.MaxValue);
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ namespace ArchiveLater.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ContentShape("Parts_ArchiveLater_Edit",
|
return ContentShape("Parts_ArchiveLater_Edit",
|
||||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/ArchiveLater", Model: model, Prefix: Prefix));
|
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,4 +9,4 @@ Features:
|
|||||||
Orchard.ArchiveLater:
|
Orchard.ArchiveLater:
|
||||||
Description: Scheduled archiving.
|
Description: Scheduled archiving.
|
||||||
Category: Content
|
Category: Content
|
||||||
Dependencies: Common, Settings
|
Dependencies: Common, Settings, Orchard.jQuery
|
||||||
|
@@ -21,7 +21,10 @@
|
|||||||
@Html.EditorFor(m => m.ScheduledArchiveTime)
|
@Html.EditorFor(m => m.ScheduledArchiveTime)
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<script type="text/javascript"> $(function () {
|
@using(Script.Foot()) {
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
$(function () {
|
||||||
//todo: (heskew) make a plugin
|
//todo: (heskew) make a plugin
|
||||||
$("label.forpicker").each(function () {
|
$("label.forpicker").each(function () {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
@@ -34,6 +37,9 @@
|
|||||||
.blur(function () { var $this = $(this); setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) });
|
.blur(function () { var $this = $(this); setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(@string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveDate"))).datepicker({ showAnim: "" }).focus(function () { $(@string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater"))).attr("checked", "checked") });
|
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveDate")').datepicker({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater")').attr("checked", "checked") });
|
||||||
$(@string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveTime"))).timepickr().focus(function () { $(@string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater"))).attr("checked", "checked") });
|
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledArchiveTime")').timepickr().focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_ArchiveLater")').attr("checked", "checked") });
|
||||||
})</script>
|
})
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
}
|
@@ -10,7 +10,7 @@
|
|||||||
<select id="sourceId" name="sourceId">
|
<select id="sourceId" name="sourceId">
|
||||||
@Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())
|
@Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())
|
||||||
@foreach (var source in Model.Sources) {
|
@foreach (var source in Model.Sources) {
|
||||||
Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle);
|
@Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle)
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<button type="submit">@T("Apply")</button>
|
<button type="submit">@T("Apply")</button>
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
<select id="sourceId" name="sourceId">
|
<select id="sourceId" name="sourceId">
|
||||||
@Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())
|
@Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())
|
||||||
@foreach (var source in Model.Sources) {
|
@foreach (var source in Model.Sources) {
|
||||||
Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle);
|
@Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle)
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<button type="submit">@T("Apply")</button>
|
<button type="submit">@T("Apply")</button>
|
||||||
|
@@ -6,6 +6,7 @@ using System.Web.Mvc;
|
|||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Orchard.Caching;
|
using Orchard.Caching;
|
||||||
|
using Orchard.Data;
|
||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Environment.State;
|
using Orchard.Environment.State;
|
||||||
@@ -48,6 +49,8 @@ namespace Orchard.Commands {
|
|||||||
tenant = tenant ?? "Default";
|
tenant = tenant ?? "Default";
|
||||||
|
|
||||||
using (var env = CreateStandaloneEnvironment(tenant)) {
|
using (var env = CreateStandaloneEnvironment(tenant)) {
|
||||||
|
var commandManager = env.Resolve<ICommandManager>();
|
||||||
|
var transactionManager = env.Resolve<ITransactionManager>();
|
||||||
|
|
||||||
var parameters = new CommandParameters {
|
var parameters = new CommandParameters {
|
||||||
Arguments = args,
|
Arguments = args,
|
||||||
@@ -56,7 +59,16 @@ namespace Orchard.Commands {
|
|||||||
Output = output
|
Output = output
|
||||||
};
|
};
|
||||||
|
|
||||||
env.Resolve<ICommandManager>().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
|
// in effect "pump messages" see PostMessage circa 1980
|
||||||
|
@@ -42,11 +42,11 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ContentShapeResult ContentShape(string shapeType, Func<dynamic, dynamic> factory) {
|
public ContentShapeResult ContentShape(string shapeType, Func<dynamic, dynamic> 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<dynamic, dynamic> factory) {
|
public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func<dynamic, dynamic> factory) {
|
||||||
return ContentShapeImplementation(shapeType, defaultLocation, factory);
|
return ContentShapeImplementation(shapeType, defaultLocation, ctx => factory(CreateShape(ctx, shapeType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContentShapeResult ContentShapeImplementation(string shapeType, string defaultLocation, Func<BuildShapeContext, object> shapeBuilder) {
|
private ContentShapeResult ContentShapeImplementation(string shapeType, string defaultLocation, Func<BuildShapeContext, object> shapeBuilder) {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
|
using Orchard.Data;
|
||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|
||||||
@@ -57,9 +58,20 @@ namespace Orchard.Tasks {
|
|||||||
public void DoWork() {
|
public void DoWork() {
|
||||||
// makes an inner container, similar to the per-request container
|
// makes an inner container, similar to the per-request container
|
||||||
using (var scope = _workContextAccessor.CreateWorkContextScope()) {
|
using (var scope = _workContextAccessor.CreateWorkContextScope()) {
|
||||||
// resolve the manager and invoke it
|
var transactionManager = scope.Resolve<ITransactionManager>();
|
||||||
var manager = scope.Resolve<IBackgroundService>();
|
|
||||||
manager.Sweep();
|
try {
|
||||||
|
// resolve the manager and invoke it
|
||||||
|
var manager = scope.Resolve<IBackgroundService>();
|
||||||
|
manager.Sweep();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// any database changes in this using scope are invalidated
|
||||||
|
transactionManager.Cancel();
|
||||||
|
|
||||||
|
// pass exception along to actual handler
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user