From fdae78826bb677298021ee3e57845f6aee474a29 Mon Sep 17 00:00:00 2001 From: skewed Date: Thu, 21 Jan 2010 20:17:40 +0000 Subject: [PATCH] - Changing all BlogPost admin actions to use the post's id instead of slug (since only published slugs are guaranteed to be unique in any container) - Changing the BlogPost publish action to POST only - Changing how BlogPosts are published on create to get the publishing/published events fired (temp workaround) - Adding unique slug generation on publish for out of the editor for a unique published slug guarantee --HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045793 --- .../Controllers/BlogAdminController.cs | 4 +- .../Controllers/BlogController.cs | 1 - .../Controllers/BlogPostAdminController.cs | 31 +++++++++------- .../Controllers/BlogPostDriver.cs | 3 +- .../Extensions/UrlHelperExtensions.cs | 12 +++--- .../Orchard.Blogs/Models/BlogPostHandler.cs | 37 ++++++++++++++++++- .../Packages/Orchard.Blogs/Routes.cs | 20 +++++++++- .../Orchard.Blogs/Services/BlogPostService.cs | 8 ++++ .../Services/IBlogPostService.cs | 2 + .../Items/Blogs.BlogPost.SummaryAdmin.ascx | 16 +++++--- .../Items/Blogs.BlogPost.ascx | 2 +- .../Views/Orchard.Blogs/BlogPost/Item.ascx | 2 +- 12 files changed, 102 insertions(+), 36 deletions(-) diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogAdminController.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogAdminController.cs index 0f9cdb7fc..4bd5363f1 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogAdminController.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogAdminController.cs @@ -39,7 +39,7 @@ namespace Orchard.Blogs.Controllers { if (!_authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to create blogs"))) return new HttpUnauthorizedResult(); - Blog blog = _services.ContentManager.New("blog"); + Blog blog = _services.ContentManager.New(BlogDriver.ContentType.Name); if (blog == null) return new NotFoundResult(); @@ -57,7 +57,7 @@ namespace Orchard.Blogs.Controllers { if (!_authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't create blog"))) return new HttpUnauthorizedResult(); - model.Blog = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New("blog"), this); + model.Blog = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New(BlogDriver.ContentType.Name), this); if (!ModelState.IsValid) return View(model); diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogController.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogController.cs index db312d61f..08b21ddd8 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogController.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogController.cs @@ -1,6 +1,5 @@ using System.Linq; using System.Web.Mvc; -using System.Web.Routing; using Orchard.Blogs.Models; using Orchard.Blogs.Services; using Orchard.Blogs.ViewModels; diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostAdminController.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostAdminController.cs index 0b58237b1..473d63c0f 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostAdminController.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostAdminController.cs @@ -41,7 +41,7 @@ namespace Orchard.Blogs.Controllers { if (blog == null) return new NotFoundResult(); - var blogPost = _services.ContentManager.New("blogpost"); + var blogPost = _services.ContentManager.New(BlogPostDriver.ContentType.Name); blogPost.Blog = blog; var model = new CreateBlogPostViewModel { @@ -74,19 +74,21 @@ namespace Orchard.Blogs.Controllers { } } - model.BlogPost = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New("blogpost"), this); + model.BlogPost = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New(BlogPostDriver.ContentType.Name), this); model.BlogPost.Item.Blog = blog; if (!publishNow && publishDate != null) model.BlogPost.Item.Published = publishDate.Value; if (!ModelState.IsValid) { _services.TransactionManager.Cancel(); - return View(model); } - //TODO: (erikpo) Evaluate if publish options should be moved into create or out of create to keep it clean - _services.ContentManager.Create(model.BlogPost.Item.ContentItem, publishNow ? VersionOptions.Published : VersionOptions.Draft); + //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); + + if (publishNow) + _services.ContentManager.Publish(model.BlogPost.Item.ContentItem); //TEMP: (erikpo) ensure information has committed for this record var session = _sessionLocator.For(typeof(ContentItemRecord)); @@ -95,7 +97,7 @@ namespace Orchard.Blogs.Controllers { return Redirect(Url.BlogPost(blogSlug, model.BlogPost.Item.As().Slug)); } - public ActionResult Edit(string blogSlug, string postSlug) { + public ActionResult Edit(string blogSlug, int postId) { if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post"))) return new HttpUnauthorizedResult(); @@ -105,7 +107,7 @@ namespace Orchard.Blogs.Controllers { if (blog == null) return new NotFoundResult(); - BlogPost post = _blogPostService.Get(blog, postSlug, VersionOptions.Latest); + BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); if (post == null) return new NotFoundResult(); @@ -118,7 +120,7 @@ namespace Orchard.Blogs.Controllers { } [HttpPost, ActionName("Edit")] - public ActionResult EditPOST(string blogSlug, string postSlug) { + public ActionResult EditPOST(string blogSlug, int postId) { if (!_services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post"))) return new HttpUnauthorizedResult(); @@ -130,7 +132,7 @@ namespace Orchard.Blogs.Controllers { if (blog == null) return new NotFoundResult(); - BlogPost post = _blogPostService.Get(blog, postSlug, VersionOptions.Latest); + BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); if (post == null) return new NotFoundResult(); @@ -172,13 +174,13 @@ namespace Orchard.Blogs.Controllers { _services.Notifier.Information(T("Blog post information updated.")); if (isDraft) { - return Redirect(Url.BlogPostEdit(blog.Slug, post.Slug)); + return Redirect(Url.BlogPostEdit(blog.Slug, post.Id)); } return Redirect(Url.BlogForAdmin(blog.Slug)); } [HttpPost] - public ActionResult Delete(string blogSlug, string postSlug) { + public ActionResult Delete(string blogSlug, int postId) { //refactoring: test PublishBlogPost/PublishOthersBlogPost in addition if published if (!_services.Authorizer.Authorize(Permissions.DeleteBlogPost, T("Couldn't delete blog post"))) return new HttpUnauthorizedResult(); @@ -189,7 +191,7 @@ namespace Orchard.Blogs.Controllers { if (blog == null) return new NotFoundResult(); - BlogPost post = _blogPostService.Get(blog, postSlug, VersionOptions.Latest); + BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); if (post == null) return new NotFoundResult(); @@ -201,7 +203,8 @@ namespace Orchard.Blogs.Controllers { return Redirect(Url.BlogForAdmin(blogSlug)); } - public ActionResult Publish(string blogSlug, string postSlug) { + [HttpPost] + public ActionResult Publish(string blogSlug, int postId) { if (!_services.Authorizer.Authorize(Permissions.PublishBlogPost, T("Couldn't publish blog post"))) return new HttpUnauthorizedResult(); @@ -211,7 +214,7 @@ namespace Orchard.Blogs.Controllers { if (blog == null) return new NotFoundResult(); - BlogPost post = _blogPostService.Get(blog, postSlug, VersionOptions.Latest); + BlogPost post = _blogPostService.Get(postId, VersionOptions.Latest); if (post == null) return new NotFoundResult(); diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostDriver.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostDriver.cs index be71354e7..29e1e85b2 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostDriver.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Controllers/BlogPostDriver.cs @@ -111,7 +111,8 @@ namespace Orchard.Blogs.Controllers { //todo: (heskew) need better messages _orchardServices.Notifier.Warning(T("A different blog post is already published with this same slug.")); - if (post.ContentItem.VersionRecord == null || post.ContentItem.VersionRecord.Published) { + if (post.ContentItem.VersionRecord == null || post.ContentItem.VersionRecord.Published) + { var originalSlug = post.Slug; //todo: (heskew) make auto-uniqueness optional post.Slug = _routableService.GenerateUniqueSlug(post.Slug, slugsLikeThis); diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/UrlHelperExtensions.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/UrlHelperExtensions.cs index c9fb899ab..1fd84936c 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/UrlHelperExtensions.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/UrlHelperExtensions.cs @@ -50,16 +50,16 @@ namespace Orchard.Blogs.Extensions { return urlHelper.Action("Create", "BlogPostAdmin", new {blogSlug, area = "Orchard.Blogs"}); } - public static string BlogPostEdit(this UrlHelper urlHelper, string blogSlug, string postSlug) { - return urlHelper.Action("Edit", "BlogPostAdmin", new {blogSlug, postSlug, area = "Orchard.Blogs"}); + public static string BlogPostEdit(this UrlHelper urlHelper, string blogSlug, int postId) { + return urlHelper.Action("Edit", "BlogPostAdmin", new {blogSlug, postId, area = "Orchard.Blogs"}); } - public static string BlogPostDelete(this UrlHelper urlHelper, string blogSlug, string postSlug) { - return urlHelper.Action("Delete", "BlogPostAdmin", new {blogSlug, postSlug, area = "Orchard.Blogs"}); + public static string BlogPostDelete(this UrlHelper urlHelper, string blogSlug, int postId) { + return urlHelper.Action("Delete", "BlogPostAdmin", new {blogSlug, postId, area = "Orchard.Blogs"}); } - public static string BlogPostPublish(this UrlHelper urlHelper, string blogSlug, string postSlug) { - return urlHelper.Action("Publish", "BlogPostAdmin", new { blogSlug, postSlug, area = "Orchard.Blogs" }); + public static string BlogPostPublish(this UrlHelper urlHelper, string blogSlug, int postId) { + return urlHelper.Action("Publish", "BlogPostAdmin", new { blogSlug, postId, area = "Orchard.Blogs" }); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Models/BlogPostHandler.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Models/BlogPostHandler.cs index 26430c7bc..32a0d3109 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Models/BlogPostHandler.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Models/BlogPostHandler.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Text.RegularExpressions; using JetBrains.Annotations; using Orchard.Blogs.Controllers; using Orchard.Blogs.Services; @@ -7,12 +8,24 @@ using Orchard.ContentManagement; using Orchard.Core.Common.Models; using Orchard.ContentManagement.Handlers; using Orchard.Core.Common.Records; +using Orchard.Core.Common.Services; using Orchard.Data; +using Orchard.Localization; +using Orchard.UI.Notify; namespace Orchard.Blogs.Models { [UsedImplicitly] public class BlogPostHandler : ContentHandler { - public BlogPostHandler(IRepository commonRepository, IBlogPostService blogPostService) { + private readonly IBlogPostService _blogPostService; + private readonly IRoutableService _routableService; + private readonly IOrchardServices _orchardServices; + + public BlogPostHandler(IRepository commonRepository, IBlogPostService blogPostService, IRoutableService routableService, IOrchardServices orchardServices) { + _blogPostService = blogPostService; + _routableService = routableService; + _orchardServices = orchardServices; + T = NullLocalizer.Instance; + Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); @@ -24,7 +37,7 @@ namespace Orchard.Blogs.Models { // Ensure we get the "right" set of published posts for the blog blog.ContentItem.ContentManager.Flush(); - var posts = blogPostService.Get(blog, VersionOptions.Published).ToList(); + var posts = _blogPostService.Get(blog, VersionOptions.Published).ToList(); blog.PostCount = posts.Count; }); @@ -33,10 +46,30 @@ namespace Orchard.Blogs.Models { OnVersioned((context, bp1, bp2) => updateBlogPostCount(bp2.Blog)); OnRemoved((context, bp) => updateBlogPostCount(bp.Blog)); + OnPublished((context, bp) => ProcessSlug(bp)); + OnRemoved( (context, b) => blogPostService.Get(context.ContentItem.As()).ToList().ForEach( blogPost => context.ContentManager.Remove(blogPost.ContentItem))); } + + Localizer T { get; set; } + + private void ProcessSlug(BlogPost post) { + _routableService.FillSlug(post.As()); + + var slugsLikeThis = _blogPostService.Get(post.Blog, VersionOptions.Published).Where( + p => p.Slug.StartsWith(post.Slug, StringComparison.OrdinalIgnoreCase) && + p.Id != post.Id).Select(p => p.Slug); + + //todo: (heskew) need better messages + if (slugsLikeThis.Count() > 0) { + //todo: (heskew) need better messages + var originalSlug = post.Slug; + post.Slug = _routableService.GenerateUniqueSlug(post.Slug, slugsLikeThis); + _orchardServices.Notifier.Warning(T("A different blog post is already published with this same slug ({0}) so a unique slug ({1}) was generated for this post.", originalSlug, post.Slug)); + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Routes.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Routes.cs index 76bf64363..31f69a315 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Routes.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Routes.cs @@ -101,7 +101,7 @@ namespace Orchard.Blogs { }, new RouteDescriptor { Route = new Route( - "Admin/Blogs/{blogSlug}/Posts/{postSlug}/Edit", + "Admin/Blogs/{blogSlug}/Posts/{postId}/Edit", new RouteValueDictionary { {"area", "Orchard.Blogs"}, {"controller", "BlogPostAdmin"}, @@ -117,7 +117,7 @@ namespace Orchard.Blogs { }, new RouteDescriptor { Route = new Route( - "Admin/Blogs/{blogSlug}/Posts/{postSlug}/Delete", + "Admin/Blogs/{blogSlug}/Posts/{postId}/Delete", new RouteValueDictionary { {"area", "Orchard.Blogs"}, {"controller", "BlogPostAdmin"}, @@ -131,6 +131,22 @@ namespace Orchard.Blogs { }, new MvcRouteHandler()) }, + new RouteDescriptor { + Route = new Route( + "Admin/Blogs/{blogSlug}/Posts/{postId}/Publish", + new RouteValueDictionary { + {"area", "Orchard.Blogs"}, + {"controller", "BlogPostAdmin"}, + {"action", "Publish"} + }, + new RouteValueDictionary { + {"blogSlug", new IsBlogConstraint(_containerProvider)} + }, + new RouteValueDictionary { + {"area", "Orchard.Blogs"} + }, + new MvcRouteHandler()) + }, new RouteDescriptor { Route = new Route( "Admin/Blogs", diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Services/BlogPostService.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Services/BlogPostService.cs index 0f2985031..117b56bda 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Services/BlogPostService.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Services/BlogPostService.cs @@ -25,6 +25,14 @@ namespace Orchard.Blogs.Services { SingleOrDefault().As(); } + public BlogPost Get(int id) { + return Get(id, VersionOptions.Published); + } + + public BlogPost Get(int id, VersionOptions versionOptions) { + return _contentManager.Get(id, versionOptions); + } + public IEnumerable Get(Blog blog) { return Get(blog, VersionOptions.Published); } diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Services/IBlogPostService.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Services/IBlogPostService.cs index 6f16db120..77f6afb0f 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Services/IBlogPostService.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Services/IBlogPostService.cs @@ -7,6 +7,8 @@ namespace Orchard.Blogs.Services { public interface IBlogPostService : IDependency { BlogPost Get(Blog blog, string slug); BlogPost Get(Blog blog, string slug, VersionOptions versionOptions); + BlogPost Get(int id); + BlogPost Get(int id, VersionOptions versionOptions); IEnumerable Get(Blog blog); IEnumerable Get(Blog blog, VersionOptions versionOptions); IEnumerable Get(Blog blog, ArchiveData archiveData); diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.SummaryAdmin.ascx b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.SummaryAdmin.ascx index 65c90de44..55fdb5dcb 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.SummaryAdmin.ascx +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.SummaryAdmin.ascx @@ -6,19 +6,23 @@ <%@ Import Namespace="Orchard.Mvc.ViewModels"%> <%@ Import Namespace="Orchard.Blogs.Extensions"%> <%@ Import Namespace="Orchard.Blogs.Models"%> -

<%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPostEdit(Model.Item.Blog.Slug, Model.Item.Slug)) %>

+

<%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPostEdit(Model.Item.Blog.Slug, Model.Item.Id)) %>

<%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%>
<%=Model.Item.As().Text ?? string.Format("

{0}

", _Encoded("there's no content for this blog post"))%>
  • - "><%=_Encoded("Edit Post")%> + "><%=_Encoded("Edit Post")%> "><%=_Encoded("View Post")%><% - if (Model.Item.ContentItem.VersionRecord.Published == false) { // todo: (heskew) be smart about this and maybe have other contextual actions - including view/preview for view up there ^^ %> - "><%=_Encoded("Publish Post Now")%> - <% } %> + if (Model.Item.ContentItem.VersionRecord.Published == false) { // todo: (heskew) be smart about this and maybe have other contextual actions - including view/preview for view up there ^^ + using (Html.BeginFormAntiForgeryPost(Url.BlogPostPublish(Model.Item.Blog.Slug, Model.Item.Id), FormMethod.Post, new { @class = "inline" })) { %> +
    + +
    <% + } + } %>
  • - <% using (Html.BeginFormAntiForgeryPost(Url.BlogPostDelete(Model.Item.Blog.Slug, Model.Item.Slug), FormMethod.Post, new { @class = "inline" })) { %> + <% using (Html.BeginFormAntiForgeryPost(Url.BlogPostDelete(Model.Item.Blog.Slug, Model.Item.Id), FormMethod.Post, new { @class = "inline" })) { %>
    <% diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.ascx b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.ascx index 08be970c6..738470580 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.ascx +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.BlogPost.ascx @@ -3,7 +3,7 @@ <%@ Import Namespace="Orchard.Blogs.Extensions"%> <%@ Import Namespace="Orchard.Blogs.Models"%>

    <%=Html.TitleForPage(Model.Item.Title)%>

    - +