From a7f086317d6ad224c32aabe7ddfe005f21a41aa0 Mon Sep 17 00:00:00 2001 From: Benedikt Neuhold Date: Tue, 14 Apr 2015 15:15:35 -0500 Subject: [PATCH] Fixed #4905: Taxonomy term counter does not decrease. I think the problem is that the TermsPartHandler triggers the TermCountProcessor as a Task async and the TermCountProcessor used the ContentTypeId as a parameter. If a ContentItem gets deleted, the TermCountProcessor cannot access it anymore and the Terms won't getting reprocessed which results in a wrong count. I altered the ITermCountProcessor interface to accept TermPartRecordId's instead of the ContentTypeId and use this id's directly. I also had to add a call for the ITermCountProcessor in the TermService UpdateTerm method. This is because when you re-publish a ContentItem only the new Terms are available in the PublishedEvent - but also terms from the previous version needed to be processed. --- .../Handlers/TermsPartHandler.cs | 3 +- .../Services/ITermCountProcessor.cs | 2 +- .../Services/TaxonomyService.cs | 35 +++++++++++++++---- .../Services/TermCountProcessor.cs | 12 ++----- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermsPartHandler.cs index 3a8e9087d..69d1cf093 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermsPartHandler.cs @@ -91,7 +91,8 @@ namespace Orchard.Taxonomies.Handlers { // Fires off a processing engine task to run the count processing after the request so it's non-blocking. private void RecalculateCount(IProcessingEngine processingEngine, ShellSettings shellSettings, IShellDescriptorManager shellDescriptorManager, TermsPart part) { - processingEngine.AddTask(shellSettings, shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary { { "termsPartId", part.ContentItem.Id } }); + var termPartRecordIds = part.Terms.Select(t => t.TermRecord.Id).ToArray(); + processingEngine.AddTask(shellSettings, shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary { { "termPartRecordIds", termPartRecordIds } }); } diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITermCountProcessor.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITermCountProcessor.cs index ceeb3ae09..3e6fc1cad 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITermCountProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITermCountProcessor.cs @@ -7,6 +7,6 @@ using Orchard.Events; namespace Orchard.Taxonomies.Services { public interface ITermCountProcessor : IEventHandler { - void Process(int termsPartId); + void Process(params int[] termPartRecordIds); } } diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs index 600d06fdc..d59dd55b7 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs @@ -9,6 +9,9 @@ using Orchard.ContentManagement.MetaData; using Orchard.Core.Common.Models; using Orchard.Core.Title.Models; using Orchard.Data; +using Orchard.Environment.Configuration; +using Orchard.Environment.Descriptor; +using Orchard.Environment.State; using Orchard.Localization; using Orchard.Logging; using Orchard.Security; @@ -23,6 +26,10 @@ namespace Orchard.Taxonomies.Services { private readonly IAuthorizationService _authorizationService; private readonly IContentDefinitionManager _contentDefinitionManager; private readonly IOrchardServices _services; + private readonly IProcessingEngine _processingEngine; + private readonly ShellSettings _shellSettings; + private readonly IShellDescriptorManager _shellDescriptorManager; + public TaxonomyService( IRepository termContentItemRepository, @@ -30,13 +37,20 @@ namespace Orchard.Taxonomies.Services { INotifier notifier, IContentDefinitionManager contentDefinitionManager, IAuthorizationService authorizationService, - IOrchardServices services) { + IOrchardServices services, + IProcessingEngine processingEngine, + ShellSettings shellSettings, + IShellDescriptorManager shellDescriptorManager) + { _termContentItemRepository = termContentItemRepository; _contentManager = contentManager; _notifier = notifier; _authorizationService = authorizationService; _contentDefinitionManager = contentDefinitionManager; _services = services; + _processingEngine = processingEngine; + _shellSettings = shellSettings; + _shellDescriptorManager = shellDescriptorManager; Logger = NullLogger.Instance; T = NullLocalizer.Instance; @@ -208,24 +222,31 @@ namespace Orchard.Taxonomies.Services { var termsPart = contentItem.As(); // removing current terms for specific field - var fieldIndexes = termsPart.Terms.Select((t, i) => new {Term = t, Index = i}) + var termList = termsPart.Terms.Select((t, i) => new {Term = t, Index = i}) .Where(x => x.Term.Field == field) - .Select(x => x.Index) - .OrderByDescending(i => i) + .Select(x => x) + .OrderByDescending(i => i.Index) .ToList(); - - foreach(var x in fieldIndexes) { - termsPart.Terms.RemoveAt(x); + + foreach (var x in termList) { + termsPart.Terms.RemoveAt(x.Index); } // adding new terms list foreach(var term in terms) { + // Remove the newly added terms because they will get processed by the Published-Event + termList.RemoveAll(t => t.Term.Id == term.Id); termsPart.Terms.Add( new TermContentItem { TermsPartRecord = termsPart.Record, TermRecord = term.Record, Field = field }); } + + var termPartRecordIds = termList.Select(t => t.Term.TermRecord.Id).ToArray(); + _processingEngine.AddTask(_shellSettings, _shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary { { "termPartRecordIds", termPartRecordIds } }); + + } public IContentQuery GetContentItemsQuery(TermPart term, string fieldName = null) { diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TermCountProcessor.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TermCountProcessor.cs index cc1a24a96..8b908bc2c 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TermCountProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TermCountProcessor.cs @@ -15,16 +15,10 @@ namespace Orchard.Taxonomies.Services { _taxonomyService = taxonomyService; } - public void Process(int termsPartId) { - var termsPart = _contentManager.Get(termsPartId); + public void Process(params int[] termPartRecordIds) { - if (termsPart == null) { - return; - } - - // Retrieve the number of associated content items, for the whole hierarchy - foreach (var term in termsPart.Terms) { - var termPart = _taxonomyService.GetTerm(term.TermRecord.Id); + foreach (var id in termPartRecordIds) { + var termPart = _taxonomyService.GetTerm(id); while (termPart != null) { termPart.Count = (int)_taxonomyService.GetContentItemsCount(termPart);