mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
#18880: Fixing performance issues in BlogArchiveWidget
Work Item: 18880 --HG-- branch : 1.x
This commit is contained in:
@@ -12,44 +12,73 @@ using Orchard.Data;
|
||||
namespace Orchard.Blogs.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class BlogPartArchiveHandler : ContentHandler {
|
||||
// contains the creation time of a blog part before it has been changed
|
||||
private readonly Dictionary<BlogPostPart, DateTime> _previousCreatedUtc = new Dictionary<BlogPostPart,DateTime>();
|
||||
|
||||
public BlogPartArchiveHandler(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService) {
|
||||
OnVersioning<BlogPostPart>((context, bp1, bp2) => {
|
||||
var commonPart = bp1.As<CommonPart>();
|
||||
if(commonPart == null || !commonPart.CreatedUtc.HasValue || !bp1.IsPublished)
|
||||
return;
|
||||
|
||||
_previousCreatedUtc[bp2] = commonPart.CreatedUtc.Value;
|
||||
});
|
||||
|
||||
OnPublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
||||
OnUnpublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
||||
OnRemoved<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
||||
}
|
||||
|
||||
private static void RecalculateBlogArchive(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService, BlogPostPart blogPostPart) {
|
||||
private void RecalculateBlogArchive(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService, BlogPostPart blogPostPart) {
|
||||
blogArchiveRepository.Flush();
|
||||
|
||||
var commonPart = blogPostPart.As<CommonPart>();
|
||||
if(commonPart == null || !commonPart.CreatedUtc.HasValue)
|
||||
return;
|
||||
|
||||
// remove all current blog archive records
|
||||
var blogArchiveRecords =
|
||||
from bar in blogArchiveRepository.Table
|
||||
where bar.BlogPart == blogPostPart.BlogPart.Record
|
||||
select bar;
|
||||
blogArchiveRecords.ToList().ForEach(blogArchiveRepository.Delete);
|
||||
var previousCreatedUtc = _previousCreatedUtc.ContainsKey(blogPostPart) ? _previousCreatedUtc[blogPostPart] : DateTime.MinValue;
|
||||
var previousMonth = previousCreatedUtc != null ? previousCreatedUtc.Month : 0;
|
||||
var previousYear = previousCreatedUtc != null ? previousCreatedUtc.Year : 0;
|
||||
|
||||
// get all blog posts for the current blog
|
||||
var posts = blogPostService.Get(blogPostPart.BlogPart, VersionOptions.Published);
|
||||
var newCreatedUtc = commonPart.CreatedUtc;
|
||||
var newMonth = newCreatedUtc.HasValue ? newCreatedUtc.Value.Month : 0;
|
||||
var newYear = newCreatedUtc.HasValue ? newCreatedUtc.Value.Year : 0;
|
||||
|
||||
// create a dictionary of all the year/month combinations and their count of posts that are published in this blog
|
||||
var inMemoryBlogArchives = new Dictionary<DateTime, int>();
|
||||
foreach (var post in posts) {
|
||||
if (!post.Has<CommonPart>())
|
||||
continue;
|
||||
// if archives are the same there is nothing to do
|
||||
if (previousMonth == newMonth && previousYear == newYear) {
|
||||
return;
|
||||
}
|
||||
|
||||
// decrement previous archive record
|
||||
var previousArchiveRecord = blogArchiveRepository.Table
|
||||
.Where(x => x.BlogPart == blogPostPart.BlogPart.Record
|
||||
&& x.Month == previousMonth
|
||||
&& x.Year == previousYear)
|
||||
.FirstOrDefault();
|
||||
|
||||
var commonPart = post.As<CommonPart>();
|
||||
var key = new DateTime(commonPart.CreatedUtc.Value.Year, commonPart.CreatedUtc.Value.Month, 1);
|
||||
|
||||
if (inMemoryBlogArchives.ContainsKey(key))
|
||||
inMemoryBlogArchives[key]++;
|
||||
else
|
||||
inMemoryBlogArchives[key] = 1;
|
||||
if (previousArchiveRecord != null && previousArchiveRecord.PostCount > 0) {
|
||||
previousArchiveRecord.PostCount--;
|
||||
}
|
||||
|
||||
// create the new blog archive records based on the in memory values
|
||||
foreach (KeyValuePair<DateTime, int> item in inMemoryBlogArchives) {
|
||||
blogArchiveRepository.Create(new BlogPartArchiveRecord {BlogPart = blogPostPart.BlogPart.Record, Year = item.Key.Year, Month = item.Key.Month, PostCount = item.Value});
|
||||
// if previous count is now zero, delete the record
|
||||
if (previousArchiveRecord != null && previousArchiveRecord.PostCount == 0) {
|
||||
blogArchiveRepository.Delete(previousArchiveRecord);
|
||||
}
|
||||
|
||||
// increment new archive record
|
||||
var newArchiveRecord = blogArchiveRepository.Table
|
||||
.Where(x => x.BlogPart == blogPostPart.BlogPart.Record
|
||||
&& x.Month == newMonth
|
||||
&& x.Year == newYear)
|
||||
.FirstOrDefault();
|
||||
|
||||
// if record can't be found create it
|
||||
if (newArchiveRecord == null) {
|
||||
newArchiveRecord = new BlogPartArchiveRecord { BlogPart = blogPostPart.BlogPart.Record, Year = newYear, Month = newMonth, PostCount = 0 };
|
||||
blogArchiveRepository.Create(newArchiveRecord);
|
||||
}
|
||||
|
||||
newArchiveRecord.PostCount++;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user