Shifting comments count

This commit is contained in:
Sebastien Ros
2014-01-16 12:12:32 -08:00
parent 7eb3579816
commit 68e4828dfe
12 changed files with 124 additions and 31 deletions

View File

@@ -39,8 +39,6 @@ namespace Orchard.Comments.Drivers {
.List()
.ToList();
var approvedCount = comments.Count();
foreach (var item in comments) {
var shape = shapeHelper.Parts_Comment(ContentPart: item, ContentItem: item.ContentItem);
allShapes.Add(item.Id, shape);
@@ -60,7 +58,7 @@ namespace Orchard.Comments.Drivers {
return shapeHelper.Parts_ListOfComments(
List: list,
CommentCount: approvedCount);
CommentCount: part.CommentsCount);
}),
ContentShape("Parts_CommentForm",
() => {
@@ -78,33 +76,20 @@ namespace Orchard.Comments.Drivers {
if (part.CommentsShown == false)
return null;
var comments = _commentService
.GetCommentsForCommentedContent(part.ContentItem.Id);
var approvedCount = comments
.Where(x => x.Status == CommentStatus.Approved)
.Count();
var pendingCount = comments
.Where(x => x.Status == CommentStatus.Pending)
.Count();
return shapeHelper.Parts_Comments_Count(
CommentCount: approvedCount,
PendingCount: pendingCount);
CommentCount: part.CommentsCount);
}),
ContentShape("Parts_Comments_Count_SummaryAdmin",
() => {
var comments = _commentService
.GetCommentsForCommentedContent(part.ContentItem.Id);
var approvedCount = comments
.Where(x => x.Status == CommentStatus.Approved)
.Count();
var pendingCount = comments
.Where(x => x.Status == CommentStatus.Pending)
.Count();
return shapeHelper.Parts_Comments_Count_SummaryAdmin(
CommentCount: approvedCount,
CommentCount: part.CommentsCount,
PendingCount: pendingCount);
})
);

View File

@@ -32,7 +32,7 @@ namespace Orchard.Comments.Feeds {
var comments = _contentManager
.Query<CommentPart, CommentPartRecord>()
.Where(x => x.CommentedOn == commentedOn && x.Status == CommentStatus.Approved)
.Where(x => x.CommentsPartRecord.Id == commentedOn && x.Status == CommentStatus.Approved)
.OrderByDescending(x => x.CommentDateUtc)
.Slice(0, limit);

View File

@@ -1,5 +1,6 @@
using JetBrains.Annotations;
using Orchard.Comments.Models;
using Orchard.Comments.Services;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Orchard.ContentManagement;
@@ -9,7 +10,9 @@ namespace Orchard.Comments.Handlers {
public class CommentPartHandler : ContentHandler {
public CommentPartHandler(
IRepository<CommentPartRecord> commentsRepository,
IContentManager contentManager) {
IContentManager contentManager,
ICommentService commentService
) {
Filters.Add(StorageFilter.For(commentsRepository));
@@ -23,15 +26,23 @@ namespace Orchard.Comments.Handlers {
);
});
OnRemoving<CommentPart>((context, comment) => {
foreach(var response in contentManager.Query<CommentPart, CommentPartRecord>().Where(x => x.RepliedOn == comment.Id).List()) {
contentManager.Remove(response.ContentItem);
}
});
// keep CommentsPart.Count in sync
OnPublished<CommentPart>((context, part) => commentService.ProcessCommentsCount(part.CommentedOn));
OnUnpublished<CommentPart>((context, part) => commentService.ProcessCommentsCount(part.CommentedOn));
OnVersioned<CommentPart>((context, part, newVersionPart) => commentService.ProcessCommentsCount(newVersionPart.CommentedOn));
OnRemoved<CommentPart>((context, part) => commentService.ProcessCommentsCount(part.CommentedOn));
OnIndexing<CommentPart>((context, commentPart) => context.DocumentIndex
.Add("commentText", commentPart.Record.CommentText));
}
}
}

View File

@@ -9,9 +9,13 @@ using Orchard.Data.Migration;
namespace Orchard.Comments {
public class Migrations : DataMigrationImpl {
private readonly ICommentService _commentService;
private readonly IContentManager _contentManager;
public Migrations(ICommentService commentService) {
public Migrations(
ICommentService commentService,
IContentManager contentManager) {
_commentService = commentService;
_contentManager = contentManager;
}
public int Create() {
@@ -36,6 +40,7 @@ namespace Orchard.Comments {
.Column<bool>("CommentsShown")
.Column<bool>("CommentsActive")
.Column<bool>("ThreadedComments")
.Column<int>("CommentsCount")
);
ContentDefinitionManager.AlterPartDefinition("CommentPart", part => part
@@ -63,7 +68,7 @@ namespace Orchard.Comments {
.Attachable()
.WithDescription("Allows content items to be commented on."));
return 5;
return 6;
}
public int UpdateFrom1() {
@@ -149,5 +154,28 @@ namespace Orchard.Comments {
return 5;
}
public int UpdateFrom5() {
SchemaBuilder.AlterTable("CommentsPartRecord", table => table
.AddColumn<int>("CommentsCount")
);
SchemaBuilder.AlterTable("CommentPartRecord",
table => table
.CreateIndex("IDX_CommentedOn", "CommentedOn")
);
SchemaBuilder.AlterTable("CommentPartRecord",
table => table
.CreateIndex("IDX_CommentedOnContainer", "CommentedOnContainer")
);
// populate the CommentsPartRecord.CommentsCount property
foreach (var commentsPart in _contentManager.Query<CommentsPart>().List()) {
_commentService.ProcessCommentsCount(commentsPart.Id);
}
return 6;
}
}
}

View File

@@ -12,11 +12,16 @@ namespace Orchard.Comments.Models {
public virtual DateTime? CommentDateUtc { get; set; }
[StringLengthMax]
public virtual string CommentText { get; set; }
// this is a duplicate of CommentsPartRecord FK, but
// it's kept for compatibility and it can also prevent
// a lazy load if only the Id value is needed
public virtual int CommentedOn { get; set; }
public virtual int CommentedOnContainer { get; set; }
public virtual int? RepliedOn { get; set; }
public virtual decimal Position { get; set; }
// inverse relationship of CommentsPartRecord.CommentPartRecords
public virtual CommentsPartRecord CommentsPartRecord { get; set; }
}
}

View File

@@ -21,18 +21,23 @@ namespace Orchard.Comments.Models {
}
public bool CommentsShown {
get { return Record.CommentsShown; }
set { Record.CommentsShown = value; }
get { return Retrieve(x => Record.CommentsShown); }
set { Store(x => Record.CommentsShown, value); }
}
public bool CommentsActive {
get { return Record.CommentsActive; }
set { Record.CommentsActive = value; }
get { return Retrieve(x => Record.CommentsActive); }
set { Store(x => Record.CommentsActive, value); }
}
public bool ThreadedComments {
get { return Record.ThreadedComments; }
set { Record.ThreadedComments = value; }
get { return Retrieve(x => Record.ThreadedComments); }
set { Store(x => Record.ThreadedComments, value); }
}
public int CommentsCount {
get { return Retrieve(x => Record.CommentsCount); }
set { Store(x => Record.CommentsCount, value); }
}
}
}

View File

@@ -11,6 +11,7 @@ namespace Orchard.Comments.Models {
public virtual bool CommentsShown { get; set; }
public virtual bool CommentsActive { get; set; }
public virtual bool ThreadedComments { get; set; }
public virtual int CommentsCount { get; set; }
[CascadeAllDeleteOrphan]
public virtual IList<CommentPartRecord> CommentPartRecords { get; set; }

View File

@@ -80,6 +80,8 @@
<Compile Include="ResourceManifest.cs" />
<Compile Include="Rules\CommentsActions.cs" />
<Compile Include="Rules\CommentsForms.cs" />
<Compile Include="Services\CommentsCountProcessor.cs" />
<Compile Include="Services\ICommentsCountProcessor.cs" />
<Compile Include="Settings\CommentsPartSettings.cs" />
<Compile Include="Settings\CommentsPartSettingsEvents.cs" />
<Compile Include="Shapes.cs" />

View File

@@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml.Linq;
using JetBrains.Annotations;
using Orchard.Comments.Models;
using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor;
using Orchard.Environment.State;
using Orchard.Logging;
using Orchard.ContentManagement;
using Orchard.Security;
@@ -15,14 +19,24 @@ namespace Orchard.Comments.Services {
private readonly IOrchardServices _orchardServices;
private readonly IClock _clock;
private readonly IEncryptionService _encryptionService;
private readonly IProcessingEngine _processingEngine;
private readonly ShellSettings _shellSettings;
private readonly IShellDescriptorManager _shellDescriptorManager;
private readonly HashSet<int> _processedCommentsParts = new HashSet<int>();
public CommentService(
IOrchardServices orchardServices,
IClock clock,
IEncryptionService encryptionService) {
IEncryptionService encryptionService,
IProcessingEngine processingEngine,
ShellSettings shellSettings,
IShellDescriptorManager shellDescriptorManager) {
_orchardServices = orchardServices;
_clock = clock;
_encryptionService = encryptionService;
_processingEngine = processingEngine;
_shellSettings = shellSettings;
_shellDescriptorManager = shellDescriptorManager;
Logger = NullLogger.Instance;
}
@@ -44,7 +58,7 @@ namespace Orchard.Comments.Services {
public IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id) {
return GetComments()
.Where(c => c.CommentedOn == id || c.CommentedOnContainer == id);
.Where(c => c.CommentedOn == id);
}
public IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id, CommentStatus status) {
@@ -66,14 +80,23 @@ namespace Orchard.Comments.Services {
return result;
}
public void ProcessCommentsCount(int commentsPartId) {
if (!_processedCommentsParts.Contains(commentsPartId)) {
_processedCommentsParts.Add(commentsPartId);
_processingEngine.AddTask(_shellSettings, _shellDescriptorManager.GetShellDescriptor(), "ICommentsCountProcessor.Process", new Dictionary<string, object> { { "commentsPartId", commentsPartId } });
}
}
public void ApproveComment(int commentId) {
var commentPart = GetCommentWithQueryHints(commentId);
commentPart.Record.Status = CommentStatus.Approved;
ProcessCommentsCount(commentPart.CommentedOn);
}
public void UnapproveComment(int commentId) {
var commentPart = GetCommentWithQueryHints(commentId);
commentPart.Record.Status = CommentStatus.Pending;
ProcessCommentsCount(commentPart.CommentedOn);
}
public void DeleteComment(int commentId) {

View File

@@ -0,0 +1,25 @@
using Orchard.Comments.Models;
using Orchard.ContentManagement;
namespace Orchard.Comments.Services {
public class CommentsCountProcessor : ICommentsCountProcessor {
private readonly IContentManager _contentManager;
public CommentsCountProcessor(
IContentManager contentManager) {
_contentManager = contentManager;
}
public void Process(int commentsPartId) {
var commentsCount = _contentManager
.Query<CommentPart, CommentPartRecord>()
.Where(x => x.Status == CommentStatus.Approved && x.CommentedOn == commentsPartId)
.Count();
var commentsPart = _contentManager.Get<CommentsPart>(commentsPartId);
if (commentsPart != null) {
commentsPart.CommentsCount = commentsCount;
}
}
}
}

View File

@@ -11,6 +11,7 @@ namespace Orchard.Comments.Services {
CommentPart GetComment(int id);
ContentItemMetadata GetDisplayForCommentedContent(int id);
ContentItem GetCommentedContent(int id);
void ProcessCommentsCount(int commentsPartId);
void ApproveComment(int commentId);
void UnapproveComment(int commentId);
void DeleteComment(int commentId);

View File

@@ -0,0 +1,7 @@
using Orchard.Events;
namespace Orchard.Comments.Services {
public interface ICommentsCountProcessor : IEventHandler {
void Process(int commentsPartId);
}
}