diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.Summary.ascx b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.Summary.ascx index 72c6852ed..80fd49000 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.Summary.ascx +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.Summary.ascx @@ -3,5 +3,5 @@ <%@ Import Namespace="Orchard.Blogs.Extensions"%> <%@ Import Namespace="Orchard.Blogs.Models"%>

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

-
<%=_Encoded("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%>
+
<%Html.Zone("meta");%><%--<%=_Encoded("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%>--%>

<%=Html.Encode(Model.Item.Description) %>

\ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Controllers/AdminController.cs b/src/Orchard.Web/Packages/Orchard.Comments/Controllers/AdminController.cs index e1bb47b1f..20f793fd1 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Controllers/AdminController.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Controllers/AdminController.cs @@ -18,11 +18,13 @@ namespace Orchard.Comments.Controllers { [ValidateInput(false)] public class AdminController : Controller { private readonly ICommentService _commentService; + private readonly IContentManager _contentManager; private readonly IAuthorizer _authorizer; private readonly INotifier _notifier; - public AdminController(ICommentService commentService, INotifier notifier, IAuthorizer authorizer) { + public AdminController(ICommentService commentService, IContentManager contentManager, INotifier notifier, IAuthorizer authorizer) { _commentService = commentService; + _contentManager = contentManager; _authorizer = authorizer; _notifier = notifier; Logger = NullLogger.Instance; @@ -59,7 +61,7 @@ namespace Orchard.Comments.Controllers { default: throw new ArgumentOutOfRangeException(); } - var entries = comments.Select(comment => CreateCommentEntry(comment)).ToList(); + var entries = comments.Select(comment => CreateCommentEntry(comment.Record)).ToList(); var model = new CommentsIndexViewModel {Comments = entries, Options = options}; return View(model); } @@ -138,16 +140,19 @@ namespace Orchard.Comments.Controllers { if (!_authorizer.Authorize(Permissions.AddComment, T("Couldn't add comment"))) return new HttpUnauthorizedResult(); } - Comment comment = new Comment { + + CommentRecord commentRecord = new CommentRecord { Author = viewModel.Name, - CommentDate = DateTime.UtcNow, + CommentDateUtc = DateTime.UtcNow, CommentText = viewModel.CommentText, Email = viewModel.Email, SiteName = viewModel.SiteName, UserName = CurrentUser == null ? "Anonymous" : CurrentUser.UserName, CommentedOn = viewModel.CommentedOn, }; - _commentService.CreateComment(comment); + + var comment = _commentService.CreateComment(commentRecord); + if (!String.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } @@ -183,7 +188,7 @@ namespace Orchard.Comments.Controllers { default: throw new ArgumentOutOfRangeException(); } - var entries = comments.Select(comment => CreateCommentEntry(comment)).ToList(); + var entries = comments.Select(comment => CreateCommentEntry(comment.Record)).ToList(); var model = new CommentsDetailsViewModel { Comments = entries, Options = options, @@ -299,12 +304,12 @@ namespace Orchard.Comments.Controllers { try { Comment comment = _commentService.GetComment(id); var viewModel = new CommentsEditViewModel { - CommentText = comment.CommentText, - Email = comment.Email, - Id = comment.Id, - Name = comment.Author, - SiteName = comment.SiteName, - Status = comment.Status, + CommentText = comment.Record.CommentText, + Email = comment.Record.Email, + Id = comment.Record.Id, + Name = comment.Record.Author, + SiteName = comment.Record.SiteName, + Status = comment.Record.Status, }; return View(viewModel); @@ -337,8 +342,10 @@ namespace Orchard.Comments.Controllers { try { if (!_authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment"))) return new HttpUnauthorizedResult(); - int commentedOn = _commentService.GetComment(id).CommentedOn; + + int commentedOn = _commentService.GetComment(id).Record.CommentedOn; _commentService.DeleteComment(id); + if (!String.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } @@ -353,7 +360,7 @@ namespace Orchard.Comments.Controllers { } } - private CommentEntry CreateCommentEntry(Comment comment) { + private CommentEntry CreateCommentEntry(CommentRecord comment) { return new CommentEntry { Comment = comment, CommentedOn = _commentService.GetDisplayForCommentedContent(comment.CommentedOn).DisplayText, diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Extensions/HtmlHelperExtensions.cs b/src/Orchard.Web/Packages/Orchard.Comments/Extensions/HtmlHelperExtensions.cs index 5c3ffda12..e347aa403 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Extensions/HtmlHelperExtensions.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Extensions/HtmlHelperExtensions.cs @@ -2,7 +2,6 @@ using System.Web.Mvc; using System.Web.Mvc.Html; using Orchard.ContentManagement; using Orchard.Localization; -using Orchard.Mvc.Html; namespace Orchard.Comments.Extensions { public static class HtmlHelperExtensions { diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentFeedItemBuilder.cs b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentFeedItemBuilder.cs index b2c4b9974..708f3105d 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentFeedItemBuilder.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentFeedItemBuilder.cs @@ -24,7 +24,7 @@ namespace Orchard.Comments.Feeds { Localizer T { get; set; } public void Populate(FeedContext context) { - foreach (var feedItem in context.Response.Items.OfType>()) { + foreach (var feedItem in context.Response.Items.OfType>()) { var comment = feedItem.Item; var commentedOn = _contentManager.Get(feedItem.Item.CommentedOn); var commentedOnInspector = new ItemInspector( @@ -47,7 +47,7 @@ namespace Orchard.Comments.Feeds { feedItem.Element.SetElementValue("title", title); feedItem.Element.Add(link); feedItem.Element.SetElementValue("description", comment.CommentText); - feedItem.Element.SetElementValue("pubDate", comment.CommentDate);//TODO: format + feedItem.Element.SetElementValue("pubDate", comment.CommentDateUtc);//TODO: format feedItem.Element.Add(guid); } else { @@ -59,7 +59,7 @@ namespace Orchard.Comments.Feeds { context.Builder.AddProperty(context, feedItem, "title", title.ToString()); context.Builder.AddProperty(context, feedItem, "description", comment.CommentText); - context.Builder.AddProperty(context, feedItem, "published-date", Convert.ToString(comment.CommentDate)); // format? cvt to generic T? + context.Builder.AddProperty(context, feedItem, "published-date", Convert.ToString(comment.CommentDateUtc)); // format? cvt to generic T? } } } diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnContainerFeedQuery.cs b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnContainerFeedQuery.cs index f36d0692e..939e4c457 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnContainerFeedQuery.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnContainerFeedQuery.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Orchard.Comments.Models; +using Orchard.ContentManagement; using Orchard.Core.Feeds; using Orchard.Core.Feeds.Models; using Orchard.Data; @@ -7,11 +8,10 @@ using Orchard.Data; namespace Orchard.Comments.Feeds { [UsedImplicitly] public class CommentedOnContainerFeedQuery : IFeedQueryProvider, IFeedQuery { - private readonly IRepository _commentRepository; + private readonly IContentManager _contentManager; - public CommentedOnContainerFeedQuery( - IRepository commentRepository) { - _commentRepository = commentRepository; + public CommentedOnContainerFeedQuery(IContentManager contentManager) { + _contentManager = contentManager; } public FeedQueryMatch Match(FeedContext context) { @@ -29,10 +29,11 @@ namespace Orchard.Comments.Feeds { if (limitValue != null) limit = (int)limitValue.ConvertTo(typeof(int)); - var comments = _commentRepository.Fetch( - x => x.CommentedOnContainer == commentedOnContainer && x.Status == CommentStatus.Approved, - o => o.Desc(x => x.CommentDate), - 0, limit); + var comments = _contentManager + .Query() + .Where(x => x.CommentedOnContainer == commentedOnContainer && x.Status == CommentStatus.Approved) + .OrderByDescending(x => x.CommentDateUtc) + .Slice(0, limit); foreach (var comment in comments) { context.Builder.AddItem(context, comment); diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnFeedQuery.cs b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnFeedQuery.cs index 97a994644..6249a2b8d 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnFeedQuery.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Feeds/CommentedOnFeedQuery.cs @@ -7,10 +7,10 @@ using Orchard.Data; namespace Orchard.Comments.Feeds { [UsedImplicitly] public class CommentedOnFeedQuery : IFeedQueryProvider, IFeedQuery { - private readonly IRepository _commentRepository; + private readonly IRepository _commentRepository; public CommentedOnFeedQuery( - IRepository commentRepository) { + IRepository commentRepository) { _commentRepository = commentRepository; } @@ -31,7 +31,7 @@ namespace Orchard.Comments.Feeds { var comments = _commentRepository.Fetch( x => x.CommentedOn == commentedOn && x.Status == CommentStatus.Approved, - o => o.Desc(x => x.CommentDate), + o => o.Desc(x => x.CommentDateUtc), 0, limit); foreach (var comment in comments) { diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/ClosedCommentsRecord.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/ClosedCommentsRecord.cs new file mode 100644 index 000000000..f879dea56 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/ClosedCommentsRecord.cs @@ -0,0 +1,6 @@ +namespace Orchard.Comments.Models { + public class ClosedCommentsRecord { + public virtual int Id { get; set; } + public virtual int ContentItemId { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/Comment.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/Comment.cs index 81c3d2eb3..432a078b3 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/Comment.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/Comment.cs @@ -1,27 +1,6 @@ -using System; +using Orchard.ContentManagement; namespace Orchard.Comments.Models { - public class Comment { - public virtual int Id { get; set; } - public virtual string Author { get; set; } - public virtual string SiteName { get; set; } - public virtual string UserName { get; set; } - public virtual string Email { get; set; } - public virtual CommentStatus Status { get; set; } - public virtual DateTime CommentDate { get; set; } - public virtual string CommentText { get; set; } - public virtual int CommentedOn { get; set; } - public virtual int CommentedOnContainer { get; set; } + public class Comment : ContentPart { } - - public class ClosedComments { - public virtual int Id { get; set; } - public virtual int ContentItemId { get; set; } - } - - public enum CommentStatus { - Pending, - Approved, - Spam - } -} +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentDriver.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentDriver.cs new file mode 100644 index 000000000..b17b03bad --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentDriver.cs @@ -0,0 +1,19 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; + +namespace Orchard.Comments.Models { + [UsedImplicitly] + public class CommentDriver : ContentItemDriver { + public readonly static ContentType ContentType = new ContentType { + Name = "comment", + DisplayName = "Comment" + }; + + protected override ContentType GetContentType() { + return ContentType; + } + + protected override string Prefix { get { return ""; } } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentHandler.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentHandler.cs new file mode 100644 index 000000000..34f6d7671 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentHandler.cs @@ -0,0 +1,15 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement.Handlers; +using Orchard.Core.Common.Models; +using Orchard.Data; + +namespace Orchard.Comments.Models { + [UsedImplicitly] + public class CommentHandler : ContentHandler { + public CommentHandler(IRepository commentsRepository) { + Filters.Add(new ActivatingFilter(CommentDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(CommentDriver.ContentType.Name)); + Filters.Add(new StorageFilter(commentsRepository)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentRecord.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentRecord.cs new file mode 100644 index 000000000..b5e12715d --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentRecord.cs @@ -0,0 +1,16 @@ +using System; +using Orchard.ContentManagement.Records; + +namespace Orchard.Comments.Models { + public class CommentRecord : ContentPartRecord { + public virtual string Author { get; set; } + public virtual string SiteName { get; set; } + public virtual string UserName { get; set; } + public virtual string Email { get; set; } + public virtual CommentStatus Status { get; set; } + public virtual DateTime CommentDateUtc { get; set; } + public virtual string CommentText { get; set; } + public virtual int CommentedOn { get; set; } + public virtual int CommentedOnContainer { get; set; } + } +} diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentStatus.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentStatus.cs new file mode 100644 index 000000000..1613d55d1 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentStatus.cs @@ -0,0 +1,7 @@ +namespace Orchard.Comments.Models { + public enum CommentStatus { + Pending, + Approved, + Spam + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs index 2b142bd3f..21bf93aec 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using Orchard.ContentManagement; -using Orchard.ContentManagement.Records; namespace Orchard.Comments.Models { public class HasComments : ContentPart { @@ -11,8 +10,6 @@ namespace Orchard.Comments.Models { PendingComments = new List(); } - public int CommentCount { get { return Comments.Count; } } - public IList Comments { get; set; } public IList PendingComments { get; set; } @@ -26,9 +23,4 @@ namespace Orchard.Comments.Models { set { Record.CommentsActive = value; } } } - - public class HasCommentsRecord : ContentPartRecord { - public virtual bool CommentsShown { get; set; } - public virtual bool CommentsActive { get; set; } - } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainer.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainer.cs new file mode 100644 index 000000000..1c76cd21b --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainer.cs @@ -0,0 +1,6 @@ +using Orchard.ContentManagement; + +namespace Orchard.Comments.Models { + public class HasCommentsContainer : ContentPart { + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerDriver.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerDriver.cs new file mode 100644 index 000000000..da6d5f27c --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerDriver.cs @@ -0,0 +1,34 @@ +using System.Linq; +using JetBrains.Annotations; +using Orchard.Comments.ViewModels; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; +using Orchard.Core.Common.Records; + +namespace Orchard.Comments.Models { + [UsedImplicitly] + public class HasCommentsContainerDriver : ContentPartDriver { + protected override DriverResult Display(HasCommentsContainer part, string displayType) { + if (displayType == "SummaryAdmin") { + return ContentPartTemplate(CreateViewModel(part.ContentItem), "Parts/Comments.CountAdmin").Location("meta"); + } + else if (displayType.Contains("Summary")) { + return ContentPartTemplate(CreateViewModel(part.ContentItem), "Parts/Comments.Count").Location("meta"); + } + + return null; + } + + private CommentCountViewModel CreateViewModel(ContentItem contentItem) { + // Find all contents item with this part as the container + var parts = contentItem.ContentManager.Query() + .Where(rec => rec.Container == contentItem.Record).List(); + + // Count comments and create template + int count = parts.Aggregate(0, (seed, item) => seed + (ContentExtensions.Has(item) ? ContentExtensions.As(item).Comments.Count : 0)); + int pendingCount = parts.Aggregate(0, (seed, item) => seed + (item.Has() ? item.As().PendingComments.Count : 0)); + + return new CommentCountViewModel { Item = contentItem, CommentCount = count, PendingCount = pendingCount}; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerHandler.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerHandler.cs new file mode 100644 index 000000000..390fd993f --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsContainerHandler.cs @@ -0,0 +1,11 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement.Handlers; + +namespace Orchard.Comments.Models { + [UsedImplicitly] + public class HasCommentsContainerHandler : ContentHandler { + public HasCommentsContainerHandler() { + Filters.Add(new ActivatingFilter("blog")); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsDriver.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsDriver.cs index 7066d3d29..626bfbf6b 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsDriver.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsDriver.cs @@ -42,4 +42,4 @@ namespace Orchard.Comments.Models { return ContentPartTemplate(part, "Parts/Comments.HasComments").Location("primary", "99"); } } -} \ No newline at end of file +} diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsHandler.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsHandler.cs index 8b5978b4e..a86e7ce0c 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsHandler.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsHandler.cs @@ -1,6 +1,7 @@ using System.Linq; using JetBrains.Annotations; using Orchard.Comments.Services; +using Orchard.ContentManagement; using Orchard.Data; using Orchard.ContentManagement.Handlers; @@ -8,7 +9,7 @@ namespace Orchard.Comments.Models { [UsedImplicitly] public class HasCommentsHandler : ContentHandler { public HasCommentsHandler( - IRepository commentsRepository, + IContentManager contentManager, IRepository hasCommentsRepository, ICommentService commentService) { @@ -22,43 +23,25 @@ namespace Orchard.Comments.Models { }); OnLoading((context, comments) => { - comments.Comments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved).ToList(); - comments.PendingComments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Pending).ToList(); + //TODO: lazy loading? + comments.Comments = contentManager + .Query() + .Where(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved) + .List().ToList(); + + //TODO: lazy loading? + comments.PendingComments = contentManager + .Query() + .Where(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Pending) + .List().ToList(); }); OnRemoved( - (context, c) => - commentService.GetCommentsForCommentedContent(context.ContentItem.Id).ToList().ForEach( - commentsRepository.Delete)); + (context, c) => { + foreach (var comment in commentService.GetCommentsForCommentedContent(context.ContentItem.Id)) { + contentManager.Remove(comment.ContentItem); + } + }); } } -#if false - [UsedImplicitly] - public class HasCommentsContainerHandler : ContentHandler { - public HasCommentsContainerHandler() { - Filters.Add(new ActivatingFilter("blog")); - } - } - - public class HasCommentsContainer : ContentPart { - } - - public class HasCommentsContainerDriver : ContentPartDriver { - protected override DriverResult Display(HasCommentsContainer part, string displayType) { - if (displayType.Contains("Summary")) { - // Find all contents item with this part as the container - var parts = part.ContentItem.ContentManager.Query() - .Where(rec => rec.Container == part.ContentItem.Record).List(); - - // Count comments and create template - int count = parts.Aggregate(0, (seed, item) => item.Has() ? item.As().CommentCount : 0); - - var model = new CommentCountViewModel { Item = part.ContentItem, CommentCount = count }; - return ContentPartTemplate(model, "Parts/Comments.Count").Location("meta"); - } - - return null; - } - } -#endif } diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsRecord.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsRecord.cs new file mode 100644 index 000000000..b25138083 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasCommentsRecord.cs @@ -0,0 +1,8 @@ +using Orchard.ContentManagement.Records; + +namespace Orchard.Comments.Models { + public class HasCommentsRecord : ContentPartRecord { + public virtual bool CommentsShown { get; set; } + public virtual bool CommentsActive { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj b/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj index 12db268de..18ab07ec8 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj +++ b/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj @@ -68,11 +68,20 @@ + + + + + + + + - + + diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentService.cs b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentService.cs index 48dbe69ee..183d7ea5c 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentService.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Castle.Core; using JetBrains.Annotations; using Orchard.Comments.Models; using Orchard.ContentManagement.Aspects; @@ -18,7 +19,7 @@ namespace Orchard.Comments.Services { IEnumerable GetCommentsForCommentedContent(int id, CommentStatus status); Comment GetComment(int id); ContentItemMetadata GetDisplayForCommentedContent(int id); - void CreateComment(Comment comment); + Comment CreateComment(CommentRecord commentRecord); void UpdateComment(int id, string name, string email, string siteName, string commentText, CommentStatus status); void ApproveComment(int commentId); void PendComment(int commentId); @@ -29,29 +30,22 @@ namespace Orchard.Comments.Services { void EnableCommentsForCommentedContent(int id); } + [UsedImplicitly] public class CommentService : ICommentService { - private readonly IRepository _commentRepository; - private readonly IRepository _closedCommentsRepository; - private readonly IRepository _hasCommentsRepository; + private readonly IRepository _closedCommentsRepository; private readonly ICommentValidator _commentValidator; private readonly IContentManager _contentManager; - private readonly IAuthorizer _authorizer; - private readonly INotifier _notifier; - public CommentService(IRepository commentRepository, - IRepository closedCommentsRepository, + public CommentService(IRepository commentRepository, + IRepository closedCommentsRepository, IRepository hasCommentsRepository, ICommentValidator commentValidator, IContentManager contentManager, IAuthorizer authorizer, INotifier notifier) { - _commentRepository = commentRepository; _closedCommentsRepository = closedCommentsRepository; - _hasCommentsRepository = hasCommentsRepository; _commentValidator = commentValidator; _contentManager = contentManager; - _authorizer = authorizer; - _notifier = notifier; Logger = NullLogger.Instance; } @@ -62,23 +56,35 @@ namespace Orchard.Comments.Services { #region Implementation of ICommentService public IEnumerable GetComments() { - return from comment in _commentRepository.Table.ToList() select comment; + return _contentManager + .Query() + .List(); } public IEnumerable GetComments(CommentStatus status) { - return from comment in _commentRepository.Table.ToList() where comment.Status == status select comment; + return _contentManager + .Query() + .Where(c => c.Status == status) + .List(); } public IEnumerable GetCommentsForCommentedContent(int id) { - return from comment in _commentRepository.Table.ToList() where comment.CommentedOn == id select comment; + return _contentManager + .Query() + .Where(c => c.CommentedOn == id || c.CommentedOnContainer == id) + .List(); } public IEnumerable GetCommentsForCommentedContent(int id, CommentStatus status) { - return from comment in _commentRepository.Table.ToList() where comment.CommentedOn == id && comment.Status == status select comment; + return _contentManager + .Query() + .Where(c => c.CommentedOn == id || c.CommentedOnContainer == id) + .Where(ctx => ctx.Status == status) + .List(); } public Comment GetComment(int id) { - return _commentRepository.Get(id); + return _contentManager.Get(id); } public ContentItemMetadata GetDisplayForCommentedContent(int id) { @@ -88,59 +94,71 @@ namespace Orchard.Comments.Services { return _contentManager.GetItemMetadata(content); } - public void CreateComment(Comment comment) { - comment.Status = _commentValidator.ValidateComment(comment) ? CommentStatus.Pending : CommentStatus.Spam; + public Comment CreateComment(CommentRecord commentRecord) { + var comment = _contentManager.Create("comment"); + + //TODO:(rpaquay) CommentRecord should never be used as "data object" + comment.Record.Author = commentRecord.Author; + comment.Record.CommentDateUtc = commentRecord.CommentDateUtc; + comment.Record.CommentText = commentRecord.CommentText; + comment.Record.Email = commentRecord.Email; + comment.Record.SiteName = commentRecord.SiteName; + comment.Record.UserName = commentRecord.UserName; + comment.Record.CommentedOn = commentRecord.CommentedOn; + + comment.Record.Status = _commentValidator.ValidateComment(commentRecord) ? CommentStatus.Pending : CommentStatus.Spam; // store id of the next layer for large-grained operations, e.g. rss on blog - var commentedOn = _contentManager.Get(comment.CommentedOn); + //TODO:(rpaquay) Get rid of this (comment aspect takes care of container) + var commentedOn = _contentManager.Get(comment.Record.CommentedOn); if (commentedOn != null && commentedOn.Container != null) { - comment.CommentedOnContainer = commentedOn.Container.ContentItem.Id; + comment.Record.CommentedOnContainer = commentedOn.Container.ContentItem.Id; } - _commentRepository.Create(comment); + return comment; } public void UpdateComment(int id, string name, string email, string siteName, string commentText, CommentStatus status) { Comment comment = GetComment(id); - comment.Author = name; - comment.Email = email; - comment.SiteName = siteName; - comment.CommentText = commentText; - comment.Status = status; + comment.Record.Author = name; + comment.Record.Email = email; + comment.Record.SiteName = siteName; + comment.Record.CommentText = commentText; + comment.Record.Status = status; } public void ApproveComment(int commentId) { Comment comment = GetComment(commentId); - comment.Status = CommentStatus.Approved; + comment.Record.Status = CommentStatus.Approved; } public void PendComment(int commentId) { Comment comment = GetComment(commentId); - comment.Status = CommentStatus.Pending; + comment.Record.Status = CommentStatus.Pending; } public void MarkCommentAsSpam(int commentId) { Comment comment = GetComment(commentId); - comment.Status = CommentStatus.Spam; + comment.Record.Status = CommentStatus.Spam; } public void DeleteComment(int commentId) { - _commentRepository.Delete(GetComment(commentId)); + _contentManager.Remove(_contentManager.Get(commentId)); } public bool CommentsClosedForCommentedContent(int id) { - return _closedCommentsRepository.Get(x => x.ContentItemId == id) == null ? false : true; + return _closedCommentsRepository.Fetch(x => x.ContentItemId == id).Count() >= 1; } public void CloseCommentsForCommentedContent(int id) { - _closedCommentsRepository.Create(new ClosedComments { ContentItemId = id }); + if (CommentsClosedForCommentedContent(id)) + return; + _closedCommentsRepository.Create(new ClosedCommentsRecord { ContentItemId = id }); } public void EnableCommentsForCommentedContent(int id) { - ClosedComments closedComments = _closedCommentsRepository.Get(x => x.ContentItemId == id); - if (closedComments != null) { - _closedCommentsRepository.Delete(closedComments); - } + var closedComments = _closedCommentsRepository.Fetch(x => x.ContentItemId == id); + closedComments.ForEach(c => _closedCommentsRepository.Delete(c)); } #endregion diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs index 8ba56f32f..593d4c898 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs @@ -27,7 +27,7 @@ namespace Orchard.Comments.Services { #region Implementation of ICommentValidator - public bool ValidateComment(Comment comment) { + public bool ValidateComment(CommentRecord comment) { CommentSettingsRecord commentSettingsRecord = CurrentSite.As().Record; string akismetKey = commentSettingsRecord.AkismetKey; string akismetUrl = commentSettingsRecord.AkismetUrl; diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs b/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs index 000df27d9..28910931a 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs @@ -2,6 +2,6 @@ using Orchard.Comments.Models; namespace Orchard.Comments.Services { public interface ICommentValidator : IDependency { - bool ValidateComment(Comment comment); + bool ValidateComment(CommentRecord comment); } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentCountViewModel.cs b/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentCountViewModel.cs index f43f4bcdf..b11707aca 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentCountViewModel.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentCountViewModel.cs @@ -3,6 +3,9 @@ using Orchard.ContentManagement; namespace Orchard.Comments.ViewModels { public class CommentCountViewModel { + public CommentCountViewModel() { + } + public CommentCountViewModel(HasComments part) { Item = part.ContentItem; CommentCount = part.Comments.Count; diff --git a/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentsIndexViewModel.cs b/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentsIndexViewModel.cs index 3959c4165..9ab1885bf 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentsIndexViewModel.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/ViewModels/CommentsIndexViewModel.cs @@ -9,7 +9,7 @@ namespace Orchard.Comments.ViewModels { } public class CommentEntry { - public Comment Comment { get; set; } + public CommentRecord Comment { get; set; } public string CommentedOn { get; set; } public bool IsChecked { get; set; } } diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Details.aspx b/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Details.aspx index 99a92de64..7ffc677f9 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Details.aspx +++ b/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Details.aspx @@ -83,7 +83,7 @@ <%=Html.Encode(commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : commentEntry.Comment.CommentText) %><%=_Encoded(" ...") %> <% } %> - <%=commentEntry.Comment.CommentDate.ToLocalTime() %> + <%=commentEntry.Comment.CommentDateUtc.ToLocalTime() %>
  • diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Index.aspx b/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Index.aspx index 59aea954f..c91cbaa95 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Index.aspx +++ b/src/Orchard.Web/Packages/Orchard.Comments/Views/Admin/Index.aspx @@ -67,7 +67,7 @@ <%=Html.Encode(commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : commentEntry.Comment.CommentText) %><%=_Encoded(" ...") %> <% } %> - <%=commentEntry.Comment.CommentDate.ToLocalTime() %> + <%=commentEntry.Comment.CommentDateUtc.ToLocalTime() %> <%=Html.ActionLink(commentEntry.CommentedOn, "Details", new { id = commentEntry.Comment.CommentedOn }) %>
      diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Views/ListOfComments.ascx b/src/Orchard.Web/Packages/Orchard.Comments/Views/ListOfComments.ascx index 27b2516dd..d60142fe4 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Views/ListOfComments.ascx +++ b/src/Orchard.Web/Packages/Orchard.Comments/Views/ListOfComments.ascx @@ -4,13 +4,13 @@ foreach (var comment in Model) { %>
    • - <%=Html.LinkOrDefault(Html.Encode(comment.UserName), Html.Encode(comment.SiteName), new { rel = "nofollow" })%> + <%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%> <%-- todo: (heskew) need comment permalink --%> - said <%=Html.Link(Html.DateTimeRelative(comment.CommentDate), "#")%> + said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc), "#")%>
      <%-- todo: (heskew) comment text needs processing depending on comment markup style --%> -

      <%=Html.Encode(comment.CommentText) %>

      +

      <%=Html.Encode(comment.Record.CommentText)%>

    • <% } %> diff --git a/src/Orchard.Web/Themes/Green/Views/ListOfComments.ascx b/src/Orchard.Web/Themes/Green/Views/ListOfComments.ascx index 95a1b3a1d..20dfcca3c 100644 --- a/src/Orchard.Web/Themes/Green/Views/ListOfComments.ascx +++ b/src/Orchard.Web/Themes/Green/Views/ListOfComments.ascx @@ -5,11 +5,11 @@ foreach (var comment in Model) { %>
    • -

      <%=Html.Encode(comment.CommentText) %>

      +

      <%=Html.Encode(comment.Record.CommentText) %>

      -<%=Html.LinkOrDefault(Html.Encode(comment.UserName), Html.Encode(comment.SiteName), new { rel = "nofollow" })%> said <%=Html.Link(Html.DateTimeRelative(comment.CommentDate), "#")%> +<%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%> said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc), "#")%>
    • <% diff --git a/src/Orchard/ContentManagement/Handlers/ActivatingFilter.cs b/src/Orchard/ContentManagement/Handlers/ActivatingFilter.cs index 063526341..fae89861c 100644 --- a/src/Orchard/ContentManagement/Handlers/ActivatingFilter.cs +++ b/src/Orchard/ContentManagement/Handlers/ActivatingFilter.cs @@ -2,6 +2,9 @@ using System; using System.Linq; namespace Orchard.ContentManagement.Handlers { + /// + /// Filter reponsible for adding a part to a content item when content items are activated + /// public class ActivatingFilter : IContentActivatingFilter where TPart : ContentPart, new() { private readonly Func _predicate; @@ -18,5 +21,4 @@ namespace Orchard.ContentManagement.Handlers { context.Builder.Weld(); } } - } diff --git a/src/Orchard/ContentManagement/Handlers/StorageFilter.cs b/src/Orchard/ContentManagement/Handlers/StorageFilter.cs index cc4104ae3..e263cecd6 100644 --- a/src/Orchard/ContentManagement/Handlers/StorageFilter.cs +++ b/src/Orchard/ContentManagement/Handlers/StorageFilter.cs @@ -20,7 +20,6 @@ namespace Orchard.ContentManagement.Handlers { _repository = repository; } - protected override void Activated(ActivatedContentContext context, ContentPart instance) { instance.Record = new TRecord(); }