Fix Blog Post publishing to follow same logic as Pages

Scheduling, publishing, etc.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045947
This commit is contained in:
rpaquay
2010-01-25 04:42:26 +00:00
parent 031582d156
commit 741e04a2fb
10 changed files with 60 additions and 95 deletions
@@ -1,4 +1,3 @@
using System;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.Blogs.Extensions; using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
@@ -26,13 +25,10 @@ namespace Orchard.Blogs.Controllers {
private Localizer T { get; set; } private Localizer T { get; set; }
public ActionResult Create(string blogSlug) { public ActionResult Create(string blogSlug) {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Not allowed to create blog post"))) if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Not allowed to create blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
@@ -51,47 +47,36 @@ namespace Orchard.Blogs.Controllers {
if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't create blog post"))) if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't create blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
//TODO: (erikpo) Move this duplicate code somewhere else // Validate form input
DateTime? publishDate = null; var blogPost = _services.ContentManager.New<BlogPost>(BlogPostDriver.ContentType.Name);
bool publishNow = false; blogPost.Blog = blog;
if (string.Equals(Request.Form["Command"], "PublishNow")) { model.BlogPost = _services.ContentManager.UpdateEditorModel(blogPost, this);
publishNow = true;
}
else if (string.Equals(Request.Form["Command"], "PublishLater")) {
DateTime publishDateValue;
if (DateTime.TryParse(Request.Form["Published"], out publishDateValue)) {
publishDate = publishDateValue;
}
}
model.BlogPost = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New<BlogPost>(BlogPostDriver.ContentType.Name), this);
model.BlogPost.Item.Blog = blog;
if (!publishNow && publishDate != null)
model.BlogPost.Item.Published = publishDate.Value;
if (!ModelState.IsValid) { if (!ModelState.IsValid) {
_services.TransactionManager.Cancel(); _services.TransactionManager.Cancel();
return View(model); return View(model);
} }
//todo: (heskew) make it so we no longer need to set as draft on create then publish (all to get the publishing & published events fired)
_services.ContentManager.Create(model.BlogPost.Item.ContentItem, VersionOptions.Draft); _services.ContentManager.Create(model.BlogPost.Item.ContentItem, VersionOptions.Draft);
if (publishNow) // Execute publish command
_services.ContentManager.Publish(model.BlogPost.Item.ContentItem); switch (Request.Form["Command"]) {
case "PublishNow":
if (publishNow) _blogPostService.Publish(model.BlogPost.Item);
_services.Notifier.Information(T("Blog post has been published")); _services.Notifier.Information(T("Blog post has been published"));
else if (publishDate != null) break;
_services.Notifier.Information(T("Blog post has been scheduled for publishing")); case "PublishLater":
else _blogPostService.Publish(model.BlogPost.Item, model.BlogPost.Item.ScheduledPublishUtc.Value);
_services.Notifier.Information(T("Blog post draft has been saved")); _services.Notifier.Information(T("Blog post has been scheduled for publishing"));
break;
default:
_services.Notifier.Information(T("Blog post draft has been saved"));
break;
}
return Redirect(Url.BlogPostEdit(blogSlug, model.BlogPost.Item.Id)); return Redirect(Url.BlogPostEdit(blogSlug, model.BlogPost.Item.Id));
} }
@@ -100,14 +85,11 @@ namespace Orchard.Blogs.Controllers {
if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post"))) if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest);
if (post == null) if (post == null)
return new NotFoundResult(); return new NotFoundResult();
@@ -123,15 +105,12 @@ namespace Orchard.Blogs.Controllers {
if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post"))) if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
// Get draft (create a new version if needed) // Get draft (create a new version if needed)
BlogPost post = _blogPostService.Get(postId, VersionOptions.DraftRequired); BlogPost post = _blogPostService.Get(postId, VersionOptions.DraftRequired);
if (post == null) if (post == null)
return new NotFoundResult(); return new NotFoundResult();
@@ -144,37 +123,24 @@ namespace Orchard.Blogs.Controllers {
if (!ModelState.IsValid) { if (!ModelState.IsValid) {
_services.TransactionManager.Cancel(); _services.TransactionManager.Cancel();
return View(model); return View(model);
} }
//TODO: (erikpo) Move this duplicate code somewhere else // Execute publish command
DateTime? publishDate = null; switch (Request.Form["Command"]) {
bool publishNow = false; case "PublishNow":
if (string.Equals(Request.Form["Command"], "PublishNow")) { _blogPostService.Publish(model.BlogPost.Item);
publishNow = true; _services.Notifier.Information(T("Blog post has been published"));
break;
case "PublishLater":
_blogPostService.Publish(model.BlogPost.Item, model.BlogPost.Item.ScheduledPublishUtc.Value);
_services.Notifier.Information(T("Blog post has been scheduled for publishing"));
break;
default:
_blogPostService.Unpublish(model.BlogPost.Item);
_services.Notifier.Information(T("Blog post draft has been saved"));
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)
_blogPostService.Publish(post);
else if (publishDate != null)
_blogPostService.Publish(post, publishDate.Value);
else
_blogPostService.Unpublish(post);
if (publishNow)
_services.Notifier.Information(T("Blog post has been published"));
else if (publishDate != null)
_services.Notifier.Information(T("Blog post has been scheduled for publishing"));
else
_services.Notifier.Information(T("Blog post draft has been saved"));
return Redirect(Url.BlogPostEdit(blogSlug, model.BlogPost.Item.Id)); return Redirect(Url.BlogPostEdit(blogSlug, model.BlogPost.Item.Id));
} }
@@ -185,19 +151,15 @@ namespace Orchard.Blogs.Controllers {
if (!_services.Authorizer.Authorize(Permissions.DeleteBlogPost, T("Couldn't delete blog post"))) if (!_services.Authorizer.Authorize(Permissions.DeleteBlogPost, T("Couldn't delete blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest);
if (post == null) if (post == null)
return new NotFoundResult(); return new NotFoundResult();
_blogPostService.Delete(post); _blogPostService.Delete(post);
_services.Notifier.Information(T("Blog post was successfully deleted")); _services.Notifier.Information(T("Blog post was successfully deleted"));
return Redirect(Url.BlogForAdmin(blogSlug)); return Redirect(Url.BlogForAdmin(blogSlug));
@@ -208,19 +170,15 @@ namespace Orchard.Blogs.Controllers {
if (!_services.Authorizer.Authorize(Permissions.PublishBlogPost, T("Couldn't publish blog post"))) if (!_services.Authorizer.Authorize(Permissions.PublishBlogPost, T("Couldn't publish blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
Blog blog = _blogService.Get(blogSlug); Blog blog = _blogService.Get(blogSlug);
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest);
if (post == null) if (post == null)
return new NotFoundResult(); return new NotFoundResult();
_blogPostService.Publish(post); _blogPostService.Publish(post);
_services.Notifier.Information(T("Blog post information updated.")); _services.Notifier.Information(T("Blog post information updated."));
return Redirect(Url.BlogForAdmin(blog.Slug)); return Redirect(Url.BlogForAdmin(blog.Slug));
@@ -9,7 +9,7 @@ namespace Orchard.Blogs.Extensions {
} }
public static string PublishedState(this HtmlHelper htmlHelper, BlogPost blogPost) { public static string PublishedState(this HtmlHelper htmlHelper, BlogPost blogPost) {
return htmlHelper.DateTime(blogPost.Published, "Draft"); return htmlHelper.DateTime(blogPost.PublishedUtc, "Draft");
} }
public static string PublishedWhen(this HtmlHelper<BlogPost> htmlHelper) { public static string PublishedWhen(this HtmlHelper<BlogPost> htmlHelper) {
@@ -17,7 +17,7 @@ namespace Orchard.Blogs.Extensions {
} }
public static string PublishedWhen(this HtmlHelper htmlHelper, BlogPost blogPost) { public static string PublishedWhen(this HtmlHelper htmlHelper, BlogPost blogPost) {
return htmlHelper.DateTimeRelative(blogPost.Published, "as a Draft"); return htmlHelper.DateTimeRelative(blogPost.PublishedUtc, "as a Draft");
} }
} }
} }
@@ -29,10 +29,10 @@ namespace Orchard.Blogs.Models {
set { this.As<ICommonAspect>().Owner = value; } set { this.As<ICommonAspect>().Owner = value; }
} }
public DateTime? Published public DateTime? PublishedUtc {
{ get { return this.As<ICommonAspect>().VersionPublishedUtc; }
get { return this.As<CommonAspect>().PublishedUtc; }
set { this.As<CommonAspect>().PublishedUtc = value; }
} }
public DateTime? ScheduledPublishUtc { get; set;}
} }
} }
@@ -28,6 +28,8 @@ namespace Orchard.Blogs.Models {
Filters.Add(new ActivatingFilter<RoutableAspect>(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<RoutableAspect>(BlogPostDriver.ContentType.Name));
Filters.Add(new ActivatingFilter<BodyAspect>(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<BodyAspect>(BlogPostDriver.ContentType.Name));
OnLoaded<BlogPost>((context, p) => p.ScheduledPublishUtc = _blogPostService.GetScheduledPublishUtc(p));
Action<Blog> updateBlogPostCount = Action<Blog> updateBlogPostCount =
(blog => { (blog => {
// Ensure we get the "right" set of published posts for the blog // Ensure we get the "right" set of published posts for the blog
@@ -6,15 +6,18 @@ using Orchard.Blogs.Models;
using Orchard.Core.Common.Records; using Orchard.Core.Common.Records;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Data; using Orchard.Data;
using Orchard.Tasks.Scheduling;
namespace Orchard.Blogs.Services { namespace Orchard.Blogs.Services {
public class BlogPostService : IBlogPostService { public class BlogPostService : IBlogPostService {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IRepository<BlogArchiveRecord> _blogArchiveRepository; private readonly IRepository<BlogArchiveRecord> _blogArchiveRepository;
private readonly IPublishingTaskManager _publishingTaskManager;
public BlogPostService(IContentManager contentManager, IRepository<BlogArchiveRecord> blogArchiveRepository) { public BlogPostService(IContentManager contentManager, IRepository<BlogArchiveRecord> blogArchiveRepository, IPublishingTaskManager publishingTaskManager) {
_contentManager = contentManager; _contentManager = contentManager;
_blogArchiveRepository = blogArchiveRepository; _blogArchiveRepository = blogArchiveRepository;
_publishingTaskManager = publishingTaskManager;
} }
public BlogPost Get(Blog blog, string slug) { public BlogPost Get(Blog blog, string slug) {
@@ -82,25 +85,28 @@ namespace Orchard.Blogs.Services {
} }
public void Delete(BlogPost blogPost) { public void Delete(BlogPost blogPost) {
_publishingTaskManager.DeleteTasks(blogPost.ContentItem);
_contentManager.Remove(blogPost.ContentItem); _contentManager.Remove(blogPost.ContentItem);
} }
public void Publish(BlogPost blogPost) { public void Publish(BlogPost blogPost) {
_publishingTaskManager.DeleteTasks(blogPost.ContentItem);
_contentManager.Publish(blogPost.ContentItem); _contentManager.Publish(blogPost.ContentItem);
} }
public void Publish(BlogPost blogPost, DateTime publishDate) { public void Publish(BlogPost blogPost, DateTime scheduledPublishUtc) {
//TODO: Implement task scheduling _publishingTaskManager.Publish(blogPost.ContentItem, scheduledPublishUtc);
//TODO: (erikpo) This logic should move out of blogs and pages and into content manager
//if (blogPost.Published != null && blogPost.Published.Value >= DateTime.UtcNow)
// _contentManager.Unpublish(blogPost.ContentItem);
//blogPost.Published = publishDate;
} }
public void Unpublish(BlogPost blogPost) { public void Unpublish(BlogPost blogPost) {
_contentManager.Unpublish(blogPost.ContentItem); _contentManager.Unpublish(blogPost.ContentItem);
} }
public DateTime? GetScheduledPublishUtc(BlogPost blogPost) {
var task = _publishingTaskManager.GetPublishTask(blogPost.ContentItem);
return (task == null ? null : task.ScheduledUtc);
}
private IContentQuery<ContentItem, CommonRecord> GetBlogQuery(ContentPart<BlogRecord> blog, VersionOptions versionOptions) { private IContentQuery<ContentItem, CommonRecord> GetBlogQuery(ContentPart<BlogRecord> blog, VersionOptions versionOptions) {
return return
_contentManager.Query(versionOptions, BlogPostDriver.ContentType.Name).Join<CommonRecord>().Where( _contentManager.Query(versionOptions, BlogPostDriver.ContentType.Name).Join<CommonRecord>().Where(
@@ -15,7 +15,8 @@ namespace Orchard.Blogs.Services {
IEnumerable<KeyValuePair<ArchiveData, int>> GetArchives(Blog blog); IEnumerable<KeyValuePair<ArchiveData, int>> GetArchives(Blog blog);
void Delete(BlogPost blogPost); void Delete(BlogPost blogPost);
void Publish(BlogPost blogPost); void Publish(BlogPost blogPost);
void Publish(BlogPost blogPost, DateTime publishDate); void Publish(BlogPost blogPost, DateTime scheduledPublishUtc);
void Unpublish(BlogPost blogPost); void Unpublish(BlogPost blogPost);
DateTime? GetScheduledPublishUtc(BlogPost blogPost);
} }
} }
@@ -10,8 +10,8 @@
<label class="forcheckbox" for="Command_PublishNow"><%=_Encoded("Publish Now")%></label> <label class="forcheckbox" for="Command_PublishNow"><%=_Encoded("Publish Now")%></label>
</div> </div>
<div> <div>
<%=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" })%>
<label class="forcheckbox" for="Command_PublishLater"><%=_Encoded("Publish Later")%></label> <label class="forcheckbox" for="Command_PublishLater"><%=_Encoded("Publish Later")%></label>
<%=Html.EditorFor(m => m.Published) %> <%=Html.EditorFor(m => m.ScheduledPublishUtc)%>
</div> </div>
</fieldset> </fieldset>
@@ -195,8 +195,8 @@ namespace Orchard.Pages.Controllers {
Services.Notifier.Information(T("Page has been scheduled for publishing")); Services.Notifier.Information(T("Page has been scheduled for publishing"));
break; break;
default: default:
_pageService.Unpublish(model.Page.Item);
Services.Notifier.Information(T("Page draft has been saved")); Services.Notifier.Information(T("Page draft has been saved"));
_pageService.Unpublish(page);
break; break;
} }
@@ -213,7 +213,6 @@ namespace Orchard.Pages.Controllers {
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
_pageService.Delete(page); _pageService.Delete(page);
Services.Notifier.Information(T("Page was successfully deleted")); Services.Notifier.Information(T("Page was successfully deleted"));
return RedirectToAction("List"); return RedirectToAction("List");
@@ -5,5 +5,5 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%> <%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%> <%@ Import Namespace="Orchard.Blogs.Models"%>
<h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item.Blog.Slug, Model.Item.Slug)) %></h3> <h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item.Blog.Slug, Model.Item.Slug)) %></h3>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%=Html.Link(_Encoded("?? comments").ToString(), "") %></div> <div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>
<div class="postsummary"><%=Model.Item.As<BodyAspect>().Text ?? string.Format("<p><em>{0}</em></p>", _Encoded("there's no content for this blog post"))%></div> <div class="postsummary"><%=Model.Item.As<BodyAspect>().Text ?? string.Format("<p><em>{0}</em></p>", _Encoded("there's no content for this blog post"))%></div>
@@ -7,7 +7,6 @@
<h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item.Blog.Slug, Model.Item.Slug)) %></h3> <h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item.Blog.Slug, Model.Item.Slug)) %></h3>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%=Html.Link(_Encoded("?? comments").ToString(), "") %> <div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>
</div>
<div class="postsummary"><%=Model.Item.As<BodyAspect>().Text ?? string.Format("<p><em>{0}</em></p>", _Encoded("there's no content for this blog post"))%></div> <div class="postsummary"><%=Model.Item.As<BodyAspect>().Text ?? string.Format("<p><em>{0}</em></p>", _Encoded("there's no content for this blog post"))%></div>