diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 5c961652d..865694f42 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -105,6 +105,7 @@ + diff --git a/src/Orchard.Web/Core/Scheduling/Models/Task.cs b/src/Orchard.Web/Core/Scheduling/Models/Task.cs index 6d6154d9d..86b857e32 100644 --- a/src/Orchard.Web/Core/Scheduling/Models/Task.cs +++ b/src/Orchard.Web/Core/Scheduling/Models/Task.cs @@ -1,7 +1,7 @@ using System; using Orchard.ContentManagement; -using Orchard.ContentManagement.Aspects; using Orchard.Core.Scheduling.Records; +using Orchard.Tasks.Scheduling; namespace Orchard.Core.Scheduling.Models { public class Task : IScheduledTask { diff --git a/src/Orchard.Web/Core/Scheduling/Services/PublishingTaskManager.cs b/src/Orchard.Web/Core/Scheduling/Services/PublishingTaskManager.cs new file mode 100644 index 000000000..b689020d9 --- /dev/null +++ b/src/Orchard.Web/Core/Scheduling/Services/PublishingTaskManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq; +using Orchard.ContentManagement; +using Orchard.Tasks.Scheduling; + +namespace Orchard.Core.Scheduling.Services { + public class PublishingTaskManager : IPublishingTaskManager { + private const string PublishTaskType = "Publish"; + private const string UnpublishTaskType = "Unpublish"; + + private readonly IScheduledTaskManager _scheduledTaskManager; + + public PublishingTaskManager(IScheduledTaskManager scheduledTaskManager) { + _scheduledTaskManager = scheduledTaskManager; + } + + public IScheduledTask GetPublishTask(ContentItem item) { + return _scheduledTaskManager + .GetTasks(item) + .Where(task => task.TaskType == PublishTaskType) + .SingleOrDefault(); + } + + public void Publish(ContentItem item, DateTime scheduledUtc) { + DeleteTasks(item); + _scheduledTaskManager.CreateTask(PublishTaskType, scheduledUtc, item); + } + + public void DeleteTasks(ContentItem item) { + _scheduledTaskManager.DeleteTasks(item, task => task.TaskType == PublishTaskType || task.TaskType == UnpublishTaskType); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Scheduling/Services/ScheduledTaskManager.cs b/src/Orchard.Web/Core/Scheduling/Services/ScheduledTaskManager.cs index 96405399d..b050258fd 100644 --- a/src/Orchard.Web/Core/Scheduling/Services/ScheduledTaskManager.cs +++ b/src/Orchard.Web/Core/Scheduling/Services/ScheduledTaskManager.cs @@ -1,10 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Web; -using JetBrains.Annotations; using Orchard.ContentManagement; -using Orchard.ContentManagement.Aspects; using Orchard.Core.Scheduling.Models; using Orchard.Core.Scheduling.Records; using Orchard.Data; @@ -13,7 +10,6 @@ using Orchard.Tasks.Scheduling; using Orchard.Utility; namespace Orchard.Core.Scheduling.Services { - [UsedImplicitly] public class ScheduledTaskManager : IScheduledTaskManager { private readonly IRepository _repository; @@ -46,5 +42,17 @@ namespace Orchard.Core.Scheduling.Services { .Cast() .ToReadOnlyCollection(); } + + public void DeleteTasks(ContentItem contentItem, Func predicate) { + //TEMP: Is this thread safe? Does it matter? + var tasks = _repository + .Fetch(x => x.ContentItemVersionRecord.ContentItemRecord == contentItem.Record); + + foreach (var task in tasks) { + if (predicate(new Task(Services.ContentManager, task))) { + _repository.Delete(task); + } + } + } } } diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Controllers/AdminController.cs b/src/Orchard.Web/Packages/Orchard.Pages/Controllers/AdminController.cs index 551084222..009fc8ecd 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Controllers/AdminController.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Controllers/AdminController.cs @@ -119,25 +119,10 @@ namespace Orchard.Pages.Controllers { if (!Services.Authorizer.Authorize(Permissions.EditPages, T("Couldn't create page"))) return new HttpUnauthorizedResult(); - //TODO: (erikpo) Move this duplicate code somewhere else - DateTime? publishDate = null; - bool publishNow = false; - if (string.Equals(Request.Form["Command"], "PublishNow")) { - publishNow = true; - } - else if (string.Equals(Request.Form["Command"], "PublishLater")) { - DateTime publishDateValue; - if (DateTime.TryParse(Request.Form["Published"], out publishDateValue)) { - publishDate = publishDateValue; - } - } - + // Validate form input var page = Services.ContentManager.New("page"); model.Page = Services.ContentManager.UpdateEditorModel(page, this); - if (!publishNow && publishDate != null) - model.Page.Item.Published = publishDate.Value; - if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); return View(model); @@ -145,15 +130,20 @@ namespace Orchard.Pages.Controllers { Services.ContentManager.Create(model.Page.Item.ContentItem, VersionOptions.Draft); - if (publishNow) - Services.ContentManager.Publish(model.Page.Item.ContentItem); - - if (publishNow) - Services.Notifier.Information(T("Page has been published")); - else if (publishDate != null) - Services.Notifier.Information(T("Page has been scheduled for publishing")); - else - Services.Notifier.Information(T("Page draft has been saved")); + // Execute publish command + switch (Request.Form["Command"]) { + case "PublishNow": + _pageService.Publish(model.Page.Item); + Services.Notifier.Information(T("Page has been published")); + break; + case "PublishLater": + _pageService.Publish(model.Page.Item, model.Page.Item.ScheduledPublishUtc.Value); + Services.Notifier.Information(T("Page has been scheduled for publishing")); + break; + default: + Services.Notifier.Information(T("Page draft has been saved")); + break; + } return RedirectToAction("Edit", "Admin", new { id = model.Page.Item.ContentItem.Id }); } @@ -191,37 +181,24 @@ namespace Orchard.Pages.Controllers { if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); - return View(model); } - //TODO: (erikpo) Move this duplicate code somewhere else - DateTime? publishDate = null; - bool publishNow = false; - if (string.Equals(Request.Form["Command"], "PublishNow")) { - publishNow = true; + // Execute publish command + switch (Request.Form["Command"]) { + case "PublishNow": + _pageService.Publish(model.Page.Item); + Services.Notifier.Information(T("Page has been published")); + break; + case "PublishLater": + _pageService.Publish(model.Page.Item, model.Page.Item.ScheduledPublishUtc.Value); + Services.Notifier.Information(T("Page has been scheduled for publishing")); + break; + default: + Services.Notifier.Information(T("Page draft has been saved")); + _pageService.Unpublish(page); + break; } - else if (string.Equals(Request.Form["Command"], "PublishLater")) { - DateTime publishDateValue; - if (DateTime.TryParse(Request.Form["Published"], out publishDateValue)) { - publishDate = publishDateValue; - } - } - - //TODO: (erikpo) Move this duplicate code somewhere else - if (publishNow) - _pageService.Publish(page); - else if (publishDate != null) - _pageService.Publish(page, publishDate.Value); - else - _pageService.Unpublish(page); - - if (publishNow) - Services.Notifier.Information(T("Page has been published")); - else if (publishDate != null) - Services.Notifier.Information(T("Page has been scheduled for publishing")); - else - Services.Notifier.Information(T("Page draft has been saved")); return RedirectToAction("Edit", "Admin", new { id = model.Page.Item.ContentItem.Id }); } diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Controllers/PageDriver.cs b/src/Orchard.Web/Packages/Orchard.Pages/Controllers/PageDriver.cs index 17a94aa27..de2902e2a 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Controllers/PageDriver.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Controllers/PageDriver.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Text.RegularExpressions; using System.Web.Routing; -using JetBrains.Annotations; using Orchard.Core.Common.Models; using Orchard.Core.Common.Services; using Orchard.Localization; @@ -13,7 +12,6 @@ using Orchard.Pages.Services; using Orchard.UI.Notify; namespace Orchard.Pages.Controllers { - [UsedImplicitly] public class PageDriver : ContentItemDriver { private readonly IPageService _pageService; private readonly IRoutableService _routableService; diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Models/Page.cs b/src/Orchard.Web/Packages/Orchard.Pages/Models/Page.cs index 33c65f459..f7d9156a0 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Models/Page.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Models/Page.cs @@ -57,12 +57,6 @@ namespace Orchard.Pages.Models { } } - public DateTime? Published { - get { return this.As().PublishedUtc; } - set { this.As().PublishedUtc = value; } - } - - //[CascadeAllDeleteOrphan] - //public virtual IList Scheduled { get; protected set; } + public DateTime? ScheduledPublishUtc { get; set;} } } diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Models/PageHandler.cs b/src/Orchard.Web/Packages/Orchard.Pages/Models/PageHandler.cs index 4999dab84..7e852be4b 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Models/PageHandler.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Models/PageHandler.cs @@ -28,6 +28,7 @@ namespace Orchard.Pages.Models { Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); + OnLoaded((context, p) => p.ScheduledPublishUtc = _pageService.GetScheduledPublishUtc(p)); OnPublished((context, p) => ProcessSlug(p)); } diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Services/IPageService.cs b/src/Orchard.Web/Packages/Orchard.Pages/Services/IPageService.cs index ebb0c113e..b88cd6aa9 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Services/IPageService.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Services/IPageService.cs @@ -14,8 +14,9 @@ namespace Orchard.Pages.Services { Page GetLatest(int id); void Delete(Page page); void Publish(Page page); - void Publish(Page page, DateTime publishDate); + void Publish(Page page, DateTime scheduledPublishUtc); void Unpublish(Page page); + DateTime? GetScheduledPublishUtc(Page page); } public enum PageStatus { diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Services/PageService.cs b/src/Orchard.Web/Packages/Orchard.Pages/Services/PageService.cs index d2ea5a843..98e55cc06 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Services/PageService.cs +++ b/src/Orchard.Web/Packages/Orchard.Pages/Services/PageService.cs @@ -5,15 +5,16 @@ using Orchard.Pages.Models; using Orchard.Core.Common.Records; using Orchard.ContentManagement; using Orchard.Services; +using Orchard.Tasks.Scheduling; namespace Orchard.Pages.Services { public class PageService : IPageService { private readonly IContentManager _contentManager; - private readonly IClock _clock; + private readonly IPublishingTaskManager _publishingTaskManager; - public PageService(IContentManager contentManager, IClock clock) { + public PageService(IContentManager contentManager, IPublishingTaskManager publishingTaskManager) { _contentManager = contentManager; - _clock = clock; + _publishingTaskManager = publishingTaskManager; } public IEnumerable Get() { @@ -71,21 +72,26 @@ namespace Orchard.Pages.Services { } public void Delete(Page page) { + _publishingTaskManager.DeleteTasks(page.ContentItem); _contentManager.Remove(page.ContentItem); } public void Publish(Page page) { + _publishingTaskManager.DeleteTasks(page.ContentItem); _contentManager.Publish(page.ContentItem); } - public void Publish(Page page, DateTime publishDate) { - //TODO: Implement task scheduling - //if (page.Published != null && page.Published.Value >= _clock.UtcNow) - // _contentManager.Unpublish(page.ContentItem); + public void Publish(Page page, DateTime scheduledPublishUtc) { + _publishingTaskManager.Publish(page.ContentItem, scheduledPublishUtc); } public void Unpublish(Page page) { _contentManager.Unpublish(page.ContentItem); } + + public DateTime? GetScheduledPublishUtc(Page page) { + var task = _publishingTaskManager.GetPublishTask(page.ContentItem); + return (task == null ? null : task.ScheduledUtc); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Views/Admin/List.aspx b/src/Orchard.Web/Packages/Orchard.Pages/Views/Admin/List.aspx index b995d59cf..c5947f5dd 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Views/Admin/List.aspx +++ b/src/Orchard.Web/Packages/Orchard.Pages/Views/Admin/List.aspx @@ -90,8 +90,8 @@ foreach (var pageEntry in Model.PageEntries) <% if (!pageEntry.Page.IsPublished) { %> - <%=pageEntry.Page.Published != null - ? string.Format("{0:d}
{0:t}", pageEntry.Page.Published.Value) + <%=pageEntry.Page.ScheduledPublishUtc != null + ? string.Format("{0:d}
{0:t}", pageEntry.Page.ScheduledPublishUtc.Value) : ""%> <% } %> diff --git a/src/Orchard.Web/Packages/Orchard.Pages/Views/EditorTemplates/Parts/Pages.Page.Publish.ascx b/src/Orchard.Web/Packages/Orchard.Pages/Views/EditorTemplates/Parts/Pages.Page.Publish.ascx index 0e0d92370..7499cc7e0 100644 --- a/src/Orchard.Web/Packages/Orchard.Pages/Views/EditorTemplates/Parts/Pages.Page.Publish.ascx +++ b/src/Orchard.Web/Packages/Orchard.Pages/Views/EditorTemplates/Parts/Pages.Page.Publish.ascx @@ -2,7 +2,7 @@
<%=_Encoded("Publish Settings")%>
- <%=Html.RadioButton("Command", "SaveDraft", Model.ContentItem.VersionRecord == null || !Model.ContentItem.VersionRecord.Published, new { id = "Command_SaveDraft" }) %> + <%=Html.RadioButton("Command", "SaveDraft", Model.ContentItem.VersionRecord == null || !Model.ContentItem.VersionRecord.Published, new { id = "Command_SaveDraft" })%>
@@ -10,8 +10,8 @@
- <%=Html.RadioButton("Command", "PublishLater", Model.Published != null && Model.Published.Value > DateTime.UtcNow, new { id = "Command_PublishLater" }) %> + <%=Html.RadioButton("Command", "PublishLater", Model.ScheduledPublishUtc != null, new { id = "Command_PublishLater" }) %> - <%=Html.EditorFor(m => m.Published) %> + <%=Html.EditorFor(m => m.ScheduledPublishUtc)%>
\ No newline at end of file diff --git a/src/Orchard/Orchard.csproj b/src/Orchard/Orchard.csproj index 744f97b0a..eb5996331 100644 --- a/src/Orchard/Orchard.csproj +++ b/src/Orchard/Orchard.csproj @@ -140,6 +140,7 @@ + diff --git a/src/Orchard/Tasks/Scheduling/IPublishingTaskManager.cs b/src/Orchard/Tasks/Scheduling/IPublishingTaskManager.cs new file mode 100644 index 000000000..77c82dc9d --- /dev/null +++ b/src/Orchard/Tasks/Scheduling/IPublishingTaskManager.cs @@ -0,0 +1,10 @@ +using System; +using Orchard.ContentManagement; + +namespace Orchard.Tasks.Scheduling { + public interface IPublishingTaskManager : IDependency { + IScheduledTask GetPublishTask(ContentItem item); + void Publish(ContentItem item, DateTime scheduledUtc); + void DeleteTasks(ContentItem item); + } +} \ No newline at end of file diff --git a/src/Orchard/Tasks/Scheduling/IScheduledTask.cs b/src/Orchard/Tasks/Scheduling/IScheduledTask.cs index 8ba15a879..00e23b744 100644 --- a/src/Orchard/Tasks/Scheduling/IScheduledTask.cs +++ b/src/Orchard/Tasks/Scheduling/IScheduledTask.cs @@ -1,9 +1,10 @@ using System; +using Orchard.ContentManagement; -namespace Orchard.ContentManagement.Aspects { +namespace Orchard.Tasks.Scheduling { public interface IScheduledTask { string TaskType { get; } DateTime? ScheduledUtc { get; } ContentItem ContentItem { get; } } -} +} \ No newline at end of file diff --git a/src/Orchard/Tasks/Scheduling/IScheduledTaskManager.cs b/src/Orchard/Tasks/Scheduling/IScheduledTaskManager.cs index 558867fa5..0fa2f2401 100644 --- a/src/Orchard/Tasks/Scheduling/IScheduledTaskManager.cs +++ b/src/Orchard/Tasks/Scheduling/IScheduledTaskManager.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using Orchard.ContentManagement; -using Orchard.ContentManagement.Aspects; namespace Orchard.Tasks.Scheduling { public interface IScheduledTaskManager : IDependency { void CreateTask(string taskType, DateTime scheduledUtc, ContentItem contentItem); IEnumerable GetTasks(ContentItem contentItem); + void DeleteTasks(ContentItem contentItem, Func predicate); } } \ No newline at end of file diff --git a/src/Orchard/Tasks/Scheduling/ScheduledTaskContext.cs b/src/Orchard/Tasks/Scheduling/ScheduledTaskContext.cs index 966feb772..e36f003ca 100644 --- a/src/Orchard/Tasks/Scheduling/ScheduledTaskContext.cs +++ b/src/Orchard/Tasks/Scheduling/ScheduledTaskContext.cs @@ -1,5 +1,3 @@ -using Orchard.ContentManagement.Aspects; - namespace Orchard.Tasks.Scheduling { public class ScheduledTaskContext { public IScheduledTask Task { get; set; } diff --git a/src/Orchard/Tasks/SweepGenerator.cs b/src/Orchard/Tasks/SweepGenerator.cs index 1326f05c9..87e7cebf0 100644 --- a/src/Orchard/Tasks/SweepGenerator.cs +++ b/src/Orchard/Tasks/SweepGenerator.cs @@ -14,7 +14,7 @@ namespace Orchard.Tasks { _timer = new Timer(); _timer.Elapsed += Elapsed; Logger = NullLogger.Instance; - Interval = TimeSpan.FromMinutes(5); + Interval = TimeSpan.FromSeconds(30); } public ILogger Logger { get; set; }